[PATCH 1/2] hw/misc/bcm2835_property: Fix framebuffer with recent RPi kernels

2021-10-17 Thread Benjamin Herrenschmidt
The framebuffer driver fails to initialize with recent Raspberry Pi
kernels, such as the ones shipped in the current RaspiOS images
(with the out of tree bcm2708_fb.c driver)

The reason is that this driver uses a new firmware call to query the
number of displays, and the fallback when this call fails is broken.

So implement the call and claim we have exactly one display

Signed-off-by: Benjamin Herrenschmidt 
---
 hw/misc/bcm2835_property.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 73941bdae9..b958fa6a5c 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -269,6 +269,10 @@ static void 
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 stl_le_phys(&s->dma_as, value + 12, 0);
 resplen = 4;
 break;
+case 0x00040013: /* Get num displays */
+stl_le_phys(&s->dma_as, value + 12, 1);
+resplen = 4;
+break;
 
 case 0x00060001: /* Get DMA channels */
 /* channels 2-5 */





[PATCH 2/2] hw/misc/bcm2835_property: Add dummy Get/Set GPIO virt buf messages

2021-10-17 Thread Benjamin Herrenschmidt
Without these the RaspiOS kernel tries to ioremap some bogus address
and dumps a backtrace in the console at boot. These work around it.

The virt-gpio driver still fails to initialize but much more cleanly

Signed-off-by: Benjamin Herrenschmidt 
---
 hw/misc/bcm2835_property.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index b958fa6a5c..62037c0630 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -274,6 +274,13 @@ static void 
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 resplen = 4;
 break;
 
+case 0x00048020: /* Set GPIO virt buf */
+/* fall through */
+case 0x00040010: /* Get GPIO virt buf */
+stl_le_phys(&s->dma_as, value + 12, 0);
+resplen = 4;
+break;
+
 case 0x00060001: /* Get DMA channels */
 /* channels 2-5 */
 stl_le_phys(&s->dma_as, value + 12, 0x003C);





Re: [RFC PATCH 2/5] target/i386: Introduce FeatureWordInfo for Intel PT CPUID leaf 0xD

2021-10-17 Thread Xiaoyao Li

On 10/16/2021 12:04 AM, Eduardo Habkost wrote:

Hi,

Apologies for the delay.  Comments below:

On Thu, Sep 09, 2021 at 10:41:47PM +0800, Xiaoyao Li wrote:

CPUID leaf 0x14 subleaf 0x0 and 0x1 enumerate the resource and
capability of Intel PT.

Introduce FeatureWord FEAT_14_0_EBX, FEAT_14_1_EAX and FEAT_14_1_EBX,
and complete FEAT_14_0_ECX. Thus all the features of Intel PT can be
expanded when "-cpu host/max" and can be configured in named CPU model.

Regarding FEAT_14_1_EAX and FEAT_14_1_EBX, don't define the name for
them since each bit of them doesn't represent a standalone sub-feature
of Intel PT. However, explicitly mark them as migratable. So the
meaningful bits of them can be autoenabled in x86_cpu_expand_features().

It has special handling for FEAT_14_1_EAX[2:0], because the 3 bits as a
whole represents the number of PT ADDRn_CFG ranges. Thus it has special
handling in mark_unavailable_features() and x86_cpu_filter_features().

Signed-off-by: Xiaoyao Li 
---
  target/i386/cpu.c | 87 +--
  target/i386/cpu.h | 37 +++-
  2 files changed, 112 insertions(+), 12 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a06473c9e84c..58e98210f219 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -567,7 +567,7 @@ static CPUCacheInfo legacy_l3_cache = {
  /* generated packets which contain IP payloads have LIP values */
  #define INTEL_PT_IP_LIP  (1 << 31)
  #define INTEL_PT_ADDR_RANGES_NUM 0x2 /* Number of configurable address ranges 
*/
-#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x3
+#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x7
  #define INTEL_PT_MTC_BITMAP  (0x0249 << 16) /* Support ART(0,3,6,9) */
  #define INTEL_PT_CYCLE_BITMAP0x1fff /* Support 0,2^(0~11) */
  #define INTEL_PT_PSB_BITMAP  (0x003f << 16) /* Support 
2K,4K,8K,16K,32K,64K */
@@ -1161,17 +1161,32 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  }
  },
  
+[FEAT_14_0_EBX] = {

+.type = CPUID_FEATURE_WORD,
+.feat_names = {
+[0] = "intel-pt-cr3-filter",
+[1] = "intel-pt-PSB",


I suggest using lowercase for all feature names, as it is the
usual convention for QOM property names.


Will do it.


+[2] = "intel-pt-ip-filter",
+[3] = "intel-pt-mtc",
+[4] = "intel-pt-ptwrite",
+[5] = "intel-pt-power-event",
+[6] = "intel-pt-psb-pmi-preservation",


This has a side effect: live migration with those flags enabled
will become possible.

All bits allow enumerate support for an optional feature to be
enabled by the OS, so it means we can emulate a CPU with bit=0
CPU on a bit=1 host.  So it will be safe as long as there's no
additional state that needs to be live migrated when those
features are used.  Do we have any additional state, or all MSRs
currently being migrated are enough?


For Intel PT, QEMU already live migration support for it, but only with 
fixed PT feature set for all the CPU models + max/host. No ?



+},
+.cpuid = {
+.eax = 0x14,
+.needs_ecx = true, .ecx = 0,
+.reg = R_EBX,
+},
+},
+
  [FEAT_14_0_ECX] = {
  .type = CPUID_FEATURE_WORD,
  .feat_names = {
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, "intel-pt-lip",
+[0] = "intel-pt-topa",
+[1] = "intel-pt-multi-topa-entries",
+[2] = "intel-pt-single-range",
+[3] = "intel-pt-trace-transport-subsystem",


All bits above are also optional features to be enabled
explicitly by the OS, so it also seems OK.


+[31] = "intel-pt-lip",


This one is trickier because its value must match the host, but
it is already present in the existing code.  We already have an
explicit check for host LIP == guest LIP, so it's OK.


  },
  .cpuid = {
  .eax = 0x14,
@@ -1181,6 +1196,26 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  .tcg_features = TCG_14_0_ECX_FEATURES,
   },
  
+[FEAT_14_1_EAX] = {

+.type = CPUID_FEATURE_WORD,
+.cpuid = {
+.eax = 0x14,
+.needs_ecx = true, .ecx = 1,
+.reg = R_EAX,
+},
+.migratable_flags = ~0ull,


This one is trickier.  I see a few potential issues:

* Bits 15:3 are documented as reserved on my version of the Intel
   SDM (June 2021).  If they are reserved, I don't think we should
   make them migratable yet.  If they aren't, do you have a
   pointer to the documentation?


you are right that they are reserved.

I was just too lazy to calculate the bitmask. Will fix it.


* Bits 2:0 is a number, not a simple boolean flag.  You are
   handling this as 

Re: [PATCH 3/8] q800: use GLUE IRQ numbers instead of IRQ level for GLUE IRQs

2021-10-17 Thread Mark Cave-Ayland

On 15/10/2021 07:31, Laurent Vivier wrote:


Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :

In order to allow dynamic routing of IRQs to different IRQ levels on the CPU
depending upon port B bit 6, use GLUE IRQ numbers and map them to the the
corresponding CPU IRQ level accordingly.

Signed-off-by: Mark Cave-Ayland 
---
  hw/m68k/q800.c | 32 
  1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 15f3067811..81c335bf16 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -102,11 +102,34 @@ struct GLUEState {
  uint8_t ipr;
  };
  
+#define GLUE_IRQ_IN_VIA1   0

+#define GLUE_IRQ_IN_VIA2   1
+#define GLUE_IRQ_IN_SONIC  2
+#define GLUE_IRQ_IN_ESCC   3
+
  static void GLUE_set_irq(void *opaque, int irq, int level)
  {
  GLUEState *s = opaque;
  int i;
  
+switch (irq) {

+case GLUE_IRQ_IN_VIA1:
+irq = 5;
+break;


Perhaps you can move this patch before patch 2 to help to understand why 
GLUE_IRQ_IN_VIA1 (0) is
mapped to irq 5 (before patch 2 it would be to 0).


+
+case GLUE_IRQ_IN_VIA2:
+irq = 1;
+break;
+
+case GLUE_IRQ_IN_SONIC:
+irq = 2;
+break;
+
+case GLUE_IRQ_IN_ESCC:
+irq = 3;
+break;
+}
+
  if (level) {
  s->ipr |= 1 << irq;


perhaps you can rename here "irq" to "shift"?


Were you happy to leave this as irq? Another alternative may be to use the BIT() 
macro as suggested by Zoltan.



ATB,

Mark.



Re: [PATCH 8/8] q800: add NMI handler

2021-10-17 Thread Mark Cave-Ayland

On 16/10/2021 18:09, Laurent Vivier wrote:


Le 15/10/2021 à 22:12, Mark Cave-Ayland a écrit :

On 15/10/2021 09:40, Laurent Vivier wrote:


Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :

This allows the programmer's switch to be triggered via the monitor for 
debugging
purposes. Since the CPU level 7 interrupt is level-triggered, use a timer to 
hold
the NMI active for 100ms before releasing it again.


I'm wondering if Qemu provides another way to have a level-triggered interrupt 
in this case.

I' tried to see if keeping the button pressed on a mac kept the IRQ up (as QMP 
NMI does), but a real
mac is too slow and has to many things to display it was not really 
conclusive...


When writing the patch I rebased the outstanding MacOS patches onto the branch, 
installed Macsbug
into MacOS and used "info nmi" to break into it.

Testing glue_nmi() with:

   GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 1);
   GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 0);

i.e. a simple pulse didn't launch MacsBug at all. Keeping the NMI high launches 
MacsBug (which is
usable) but then as soon as you exit MacsBug with ES, MacsBug breaks 
immediately again making it
impossible to return to the Finder. Adding the timer allows launching MacsBug 
and then
exiting/re-entering MacsBug again on demand as expected.



I think we have to mimic the finger pressing the button..

By the way, NMI should also dumps the CPU registers under linux.

Reviewied-by: Laurent Vivier 


I've just tried this on Linux, and it seems to work okay although I get several 
copies of the register dump on the console for a single invocation of "info nmi" e.g.


[4.61] Non-Maskable Interrupt
[4.61] Modules linked in: mac_esp(+) esp_scsi macsonic
[4.61] PC: [<2dc0>] arch_cpu_idle+0x4/0x6
[4.61] SR: 2000  SP: (ptrval)  a2: 00395314
[4.61] d0: d1: 0002d2: 0004b492d3: 00392000
[4.61] d4: d5: a0: 00392000a1: 00395314
[4.61] Process swapper (pid: 0, task=(ptrval))
[4.61] Frame format=0
[4.61] Stack from 00393f9c:
[4.61] 0004b540 0431 0040ee22 0004b4c4 0002bf6a 004005f0 00393ff8 
0004b714
[4.61] 0003e23a 0029c518 00c2 0040eb54 3dc1e5d0  0004ff74 
0003efe2
[4.61] 003f4e92  0040    0040ee22 


[4.61] 003f3872
[4.61] Call Trace: [<0004b540>] do_idle+0x7c/0xd2
[4.61]  [<0004b4c4>] do_idle+0x0/0xd2
[4.61]  [<0002bf6a>] kernel_thread+0x0/0x26
[4.61]  [<004005f0>] __alloc_bootmem+0x0/0x38
[4.61]  [<0004b714>] cpu_startup_entry+0xe/0x12
[4.61]  [<0003e23a>] find_task_by_pid_ns+0x0/0x22
[4.61]  [<0029c518>] rest_init+0x78/0x82
[4.61]  [<0004ff74>] printk+0x0/0x18
[4.61]  [<0003efe2>] parse_args+0x0/0x2c2
[4.61]  [<003f4e92>] start_kernel+0x43e/0x448
[4.61]  [<003f3872>] _sinittext+0x872/0x11f8
[4.61] Code: bc00 0060 f210 f0ff 7001 60cc 4e72 2000 <4e75> 2079 003b fc6c 
4a88 6702 4e90 60fe 2079 003b fc68 4a88 6702 4e90 60fe 2f0c


(repeated 7 or 8 times)

MacsBug seems to handle this better: as soon as the NMI is triggered, MacsBug opens 
and displays "NMI" both if the programmer switch GPIO is held active, or pulsed as 
implemented in the patch. When using the above patch, subsequent NMI triggers do not 
display "NMI" or change MacsBug in any visible way which suggests that once the NMI 
is triggered, the NMI is ignored until the programmers switch GPIO is inactive once 
again.


Do you see the repeated register output in Linux for a single press of the 
programmers switch on a real Quadra 800? It may be that Linux could be improved by 
having similar logic.



ATB,

Mark.



Re: [PATCH 6/8] q800: route SONIC on-board Ethernet IRQ via nubus IRQ 9 in classic mode

2021-10-17 Thread Mark Cave-Ayland

On 16/10/2021 19:08, Laurent Vivier wrote:


Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :

When the hardware is operating in classic mode the SONIC on-board Ethernet IRQ 
is
routed to nubus IRQ 9 instead of directly to the CPU at level 3. This does not
affect the framebuffer which although it exists in slot 9, has its own
dedicated IRQ on the Quadra 800 hardware.

Signed-off-by: Mark Cave-Ayland 
---
  hw/m68k/q800.c | 57 --
  1 file changed, 46 insertions(+), 11 deletions(-)

diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 0093872d89..d55e6a7541 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -101,6 +101,7 @@ struct GLUEState {
  M68kCPU *cpu;
  uint8_t ipr;
  uint8_t auxmode;
+qemu_irq irqs[1];
  };
  
  #define GLUE_IRQ_IN_VIA1   0

@@ -108,27 +109,50 @@ struct GLUEState {
  #define GLUE_IRQ_IN_SONIC  2
  #define GLUE_IRQ_IN_ESCC   3
  
+#define GLUE_IRQ_NUBUS_9   0

+
  static void GLUE_set_irq(void *opaque, int irq, int level)
  {
  GLUEState *s = opaque;
  int i;
  
-switch (irq) {

-case GLUE_IRQ_IN_VIA1:
-irq = 5;
-break;
+switch (s->auxmode) {
+case 0:


why don't you use "if () {} else {}" rather than "switch() { case 0: ; case 1: 
}" ?
(I don't think we need to manage a "default:" case.)


Sure, I can do that: I used the switch()/default originally to make sure the irq 
wasn't being set to an unexpected value.


I've also just spotted that the comment in this patch is incorrect:

/*
 * Since the framebuffer in slot 0x9 uses a separate IRQ, wire the unused
 * IRQ via GLUE for use by SONIC Ethernet in A/UX mode
 */

This should be classic mode, of course.


ATB,

Mark.



Re: [RFC PATCH 3/5] target/i386: Enable host pass through of Intel PT

2021-10-17 Thread Xiaoyao Li

On 10/16/2021 4:22 AM, Eduardo Habkost wrote:

On Thu, Sep 09, 2021 at 10:41:48PM +0800, Xiaoyao Li wrote:

commit e37a5c7fa459 ("i386: Add Intel Processor Trace feature support")
added the support of Intel PT by making CPUID[14] of PT as fixed feature
set (from ICX) for any CPU model on any host.

This truly breaks the PT exposing on Intel SPR platform because SPR has
less supported bitmap CPUID(0x14,1):EBX[15:0] than ICX.

This patch enables passing through host's PT capabilities for the case
"-cpu host/max" while ensure named CPU model still has the fixed
PT feature set to not break the live migration.

It introduces @has_specific_intel_pt_feature_set field for name CPU
model. If a named CPU model has this field as false, it will use fixed
PT feature set of ICX. Besides same to previous behavior, if fixed PT
feature set of ICX cannot be satisfied/supported by host, it disables PT
instead of adjusting the feature set based on host's capabilities.

In the future, new named CPU model, e.g., Sapphire Rapids, can define
its own PT feature set by setting @has_specific_intel_pt_feature_set to
true and defines it's own FEAT_14_0_EBX, FEAT_14_0_ECX, FEAT_14_1_EAX
and FEAT_14_1_EBX.

Signed-off-by: Xiaoyao Li 
---
  target/i386/cpu.c | 106 --
  target/i386/cpu.h |   1 +
  2 files changed, 47 insertions(+), 60 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 58e98210f219..00c4ad23110d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -543,34 +543,24 @@ static CPUCacheInfo legacy_l3_cache = {
  #define L2_ITLB_4K_ASSOC   4
  #define L2_ITLB_4K_ENTRIES   512
  
-/* CPUID Leaf 0x14 constants: */

-#define INTEL_PT_MAX_SUBLEAF 0x1
-/*
- * bit[00]: IA32_RTIT_CTL.CR3 filter can be set to 1 and IA32_RTIT_CR3_MATCH
- *  MSR can be accessed;
- * bit[01]: Support Configurable PSB and Cycle-Accurate Mode;
- * bit[02]: Support IP Filtering, TraceStop filtering, and preservation
- *  of Intel PT MSRs across warm reset;
- * bit[03]: Support MTC timing packet and suppression of COFI-based packets;
- */
-#define INTEL_PT_MINIMAL_EBX 0xf
-/*
- * bit[00]: Tracing can be enabled with IA32_RTIT_CTL.ToPA = 1 and
- *  IA32_RTIT_OUTPUT_BASE and IA32_RTIT_OUTPUT_MASK_PTRS MSRs can be
- *  accessed;
- * bit[01]: ToPA tables can hold any number of output entries, up to the
- *  maximum allowed by the MaskOrTableOffset field of
- *  IA32_RTIT_OUTPUT_MASK_PTRS;
- * bit[02]: Support Single-Range Output scheme;
- */
-#define INTEL_PT_MINIMAL_ECX 0x7
-/* generated packets which contain IP payloads have LIP values */
-#define INTEL_PT_IP_LIP  (1 << 31)
-#define INTEL_PT_ADDR_RANGES_NUM 0x2 /* Number of configurable address ranges 
*/
-#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x7
-#define INTEL_PT_MTC_BITMAP  (0x0249 << 16) /* Support ART(0,3,6,9) */
-#define INTEL_PT_CYCLE_BITMAP0x1fff /* Support 0,2^(0~11) */
-#define INTEL_PT_PSB_BITMAP  (0x003f << 16) /* Support 
2K,4K,8K,16K,32K,64K */
+#define INTEL_PT_MAX_SUBLEAF0x1
+#define INTEL_PT_DEFAULT_ADDR_RANGES_NUM0x2
+#define INTEL_PT_ADDR_RANGES_NUM_MASK   0x7
+/* Support ART(0,3,6,9) */
+#define INTEL_PT_DEFAULT_MTC_BITMAP 0x0249
+/* Support 0,2^(0~11) */
+#define INTEL_PT_DEFAULT_CYCLE_BITMAP   0x1fff
+/* Support 2K,4K,8K,16K,32K,64K */
+#define INTEL_PT_DEFAULT_PSB_BITMAP 0x003f
+
+#define INTEL_PT_DEFAULT_0_EBX  (CPUID_14_0_EBX_CR3_FILTER | \
+CPUID_14_0_EBX_PSB | CPUID_14_0_EBX_IP_FILTER | CPUID_14_0_EBX_MTC)
+#define INTEL_PT_DEFAULT_0_ECX  (CPUID_14_0_ECX_TOPA | \
+CPUID_14_0_ECX_MULTI_ENTRIES | CPUID_14_0_ECX_SINGLE_RANGE)
+#define INTEL_PT_DEFAULT_1_EAX  (INTEL_PT_DEFAULT_MTC_BITMAP << 16 | \
+ INTEL_PT_DEFAULT_ADDR_RANGES_NUM)
+#define INTEL_PT_DEFAULT_1_EBX  (INTEL_PT_DEFAULT_PSB_BITMAP << 16 | \
+ INTEL_PT_DEFAULT_CYCLE_BITMAP)


I like these new macros because they make the code at
x86_cpu_filter_features() clearer.  Can we do this in a separate
patch, to be applied before "Introduce FeatureWordInfo for Intel
PT CPUID leaf 0xD"?

  
  void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,

uint32_t vendor2, uint32_t vendor3)
@@ -1517,6 +1507,7 @@ typedef struct X86CPUDefinition {
  int family;
  int model;
  int stepping;
+bool has_specific_intel_pt_feature_set;
  FeatureWordArray features;
  const char *model_id;
  const CPUCaches *const cache_info;
@@ -5061,6 +5052,14 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel 
*model)
  env->features[w] = def->features[w];
  }
  
+if (!def->has_specific_intel_pt_feature_set) {

+env->use_default_intel_pt = true;
+env->features[FEAT_14_0_EBX] = INTEL_PT_DEFAULT_0_EBX;
+env->features[FEAT_14_0_ECX] = INTEL_PT_DEFAULT_0_ECX;
+env->fe

Re: [PATCH 3/8] q800: use GLUE IRQ numbers instead of IRQ level for GLUE IRQs

2021-10-17 Thread Laurent Vivier
Le 17/10/2021 à 11:40, Mark Cave-Ayland a écrit :
> On 15/10/2021 07:31, Laurent Vivier wrote:
> 
>> Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :
>>> In order to allow dynamic routing of IRQs to different IRQ levels on the CPU
>>> depending upon port B bit 6, use GLUE IRQ numbers and map them to the the
>>> corresponding CPU IRQ level accordingly.
>>>
>>> Signed-off-by: Mark Cave-Ayland 
>>> ---
>>>   hw/m68k/q800.c | 32 
>>>   1 file changed, 28 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
>>> index 15f3067811..81c335bf16 100644
>>> --- a/hw/m68k/q800.c
>>> +++ b/hw/m68k/q800.c
>>> @@ -102,11 +102,34 @@ struct GLUEState {
>>>   uint8_t ipr;
>>>   };
>>>   +#define GLUE_IRQ_IN_VIA1   0
>>> +#define GLUE_IRQ_IN_VIA2   1
>>> +#define GLUE_IRQ_IN_SONIC  2
>>> +#define GLUE_IRQ_IN_ESCC   3
>>> +
>>>   static void GLUE_set_irq(void *opaque, int irq, int level)
>>>   {
>>>   GLUEState *s = opaque;
>>>   int i;
>>>   +    switch (irq) {
>>> +    case GLUE_IRQ_IN_VIA1:
>>> +    irq = 5;
>>> +    break;
>>
>> Perhaps you can move this patch before patch 2 to help to understand why 
>> GLUE_IRQ_IN_VIA1 (0) is
>> mapped to irq 5 (before patch 2 it would be to 0).
>>
>>> +
>>> +    case GLUE_IRQ_IN_VIA2:
>>> +    irq = 1;
>>> +    break;
>>> +
>>> +    case GLUE_IRQ_IN_SONIC:
>>> +    irq = 2;
>>> +    break;
>>> +
>>> +    case GLUE_IRQ_IN_ESCC:
>>> +    irq = 3;
>>> +    break;
>>> +    }
>>> +
>>>   if (level) {
>>>   s->ipr |= 1 << irq;
>>
>> perhaps you can rename here "irq" to "shift"?
> 
> Were you happy to leave this as irq? Another alternative may be to use the 
> BIT() macro as suggested
> by Zoltan.

I have no problem to keep this like that.

Thanks,
Laurent




Re: gitlab build-edk2 failures

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/16/21 09:27, Paolo Bonzini wrote:
> On 16/10/21 04:04, Richard Henderson wrote:
>> I've seen a lot of failures on this job recently, and they're all
>> timeouts cloning the git submodules.  Would it be better to mirror
>> these to gitlab?
>>
> 
> They're not timeouts, they're issues with edk2's _own_ submodules.
> 
> fatal: unable to access
> 'https://git.cryptomilk.org/projects/cmocka.git/': server certificate
> verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile:
> none
> fatal: clone of 'https://git.cryptomilk.org/projects/cmocka.git' into
> submodule path 'UnitTestFrameworkPkg/Library/CmockaLib/cmocka' failed
> 
> roms/edk2 is already mirrored to gitlab, so we'd have to add mirrors for
> all of these and make edk2.yml configure the mirrors in .git/config.  I
> think the edk2 project should do the mirroring instead...

IIUC QEMU EDK2 scripts don't require cmocka... IMHO (short term) we
should update the 'git submodule update' line in roms/Makefile.edk2
to only update the submodules we require.




Re: [PATCH 1/2] hw/misc/bcm2835_property: Fix framebuffer with recent RPi kernels

2021-10-17 Thread Philippe Mathieu-Daudé
Hi Benjamin,

On 10/17/21 09:48, Benjamin Herrenschmidt wrote:
> The framebuffer driver fails to initialize with recent Raspberry Pi
> kernels, such as the ones shipped in the current RaspiOS images
> (with the out of tree bcm2708_fb.c driver)

Which particular version?

> 
> The reason is that this driver uses a new firmware call to query the
> number of displays, and the fallback when this call fails is broken.
> 
> So implement the call and claim we have exactly one display
> 
> Signed-off-by: Benjamin Herrenschmidt 
> ---
>  hw/misc/bcm2835_property.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
> index 73941bdae9..b958fa6a5c 100644
> --- a/hw/misc/bcm2835_property.c
> +++ b/hw/misc/bcm2835_property.c
> @@ -269,6 +269,10 @@ static void 
> bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
>  stl_le_phys(&s->dma_as, value + 12, 0);
>  resplen = 4;
>  break;
> +case 0x00040013: /* Get num displays */
> +stl_le_phys(&s->dma_as, value + 12, 1);
> +resplen = 4;
> +break;
>  
>  case 0x00060001: /* Get DMA channels */
>  /* channels 2-5 */
> 

I carry (among others) this patch for the raspi4:

-- >8 --
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 3b3f5a804d9..8bd149211af 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -36,6 +36,7 @@ static void
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
  */
 BCM2835FBConfig fbconfig = s->fbdev->config;
 bool fbconfig_updated = false;
+int fbconfig_idx = 0;

 value &= ~0xf;

@@ -290,6 +291,25 @@ static void
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 resplen = 4;
 break;

+case 0x00040013: /* Get number of displays */
+stl_le_phys(&s->dma_as, value + 12, 0 /* old fw: unique
display */);
+resplen = 4;
+break;
+
+case 0x00048013: /* Select display  */
+fbconfig_idx = ldl_le_phys(&s->dma_as, value + 12);
+if (fbconfig_idx) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "bcm2835_property: Only one display
implemented,"
+  " requested display #%d\n", fbconfig_idx);
+}
+resplen = 4;
+break;
+
+case 0x00040014: /* Get display settings */
+resplen = 0; /* as old fw we don't support that */
+break;
+
 case 0x00060001: /* Get DMA channels */
 /* channels 2-5 */
 stl_le_phys(&s->dma_as, value + 12, 0x003C);
---

FYI I plan to respin Alex's recent series with these patches:
https://lore.kernel.org/qemu-devel/20211004134742.2044280-1-alex.ben...@linaro.org/
as soon as I get some time...



Re: [PATCH] via-ide: Set user_creatable to false

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/15/21 11:16, BALATON Zoltan wrote:
> This model only works as a function of the via superio chip not as a
> standalone PCI device.
> 
> Signed-off-by: BALATON Zoltan 
> ---
> This should be before the last patch changing via-ide or squshed into
> it. And similar to usb part but there I need to add it to the info
> struct. I can resend with these if you think this series worth the
> hassle. The previous one fixing the usb irq works without this clean up.
> 
>  hw/ide/via.c | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH 2/4] vt82c686: Add a method to VIA_ISA to raise ISA interrupts

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/15/21 03:06, BALATON Zoltan wrote:
> Other functions in the VT82xx chips need to raise ISA interrupts. Keep
> a reference to them in the device state and add via_isa_set_irq() to
> allow setting their state.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/isa/vt82c686.c | 10 +-
>  include/hw/isa/vt82c686.h |  4 
>  2 files changed, 13 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH 1/4] vt82c686: Move common code to via_isa_realize

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/15/21 03:06, BALATON Zoltan wrote:
> The vt82c686b_realize and vt8231_realize methods are almost identical,
> factor out the common parts to a via_isa_realize function to avoid
> code duplication.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/isa/vt82c686.c | 67 ---
>  1 file changed, 29 insertions(+), 38 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH 3/4] hw/usb/vt82c686-uhci-pci: Avoid using isa_get_irq()

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/15/21 03:06, BALATON Zoltan wrote:
> Use via_isa_set_irq() which better encapsulates irq handling in the
> vt82xx model and avoids using isa_get_irq() that has a comment saying
> it should not be used.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/usb/vt82c686-uhci-pci.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/15/21 03:06, BALATON Zoltan wrote:
> Use via_isa_set_irq() which better encapsulates irq handling in the
> vt82xx model and avoids using isa_get_irq() that has a comment saying
> it should not be used.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/ide/via.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 94cc2142c7..252d18f4ac 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -29,7 +29,7 @@
>  #include "migration/vmstate.h"
>  #include "qemu/module.h"
>  #include "sysemu/dma.h"
> -
> +#include "hw/isa/vt82c686.h"
>  #include "hw/ide/pci.h"
>  #include "trace.h"
>  
> @@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n, int 
> level)
>  d->config[0x70 + n * 8] &= ~0x80;
>  }
>  
> -qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
> +via_isa_set_irq(pci_get_function_0(d), 14 + n, level);

Since pci_get_function_0() is expensive, we should cache
'PCIDevice *func0' in PCIIDEState, setting the pointer in
via_ide_realize(). Do you mind sending a follow-up patch?

>  }

Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH V5] block/rbd: implement bdrv_co_block_status

2021-10-17 Thread Ilya Dryomov
On Tue, Oct 12, 2021 at 5:22 PM Peter Lieven  wrote:
>
> the qemu rbd driver currently lacks support for bdrv_co_block_status.
> This results mainly in incorrect progress during block operations (e.g.
> qemu-img convert with an rbd image as source).
>
> This patch utilizes the rbd_diff_iterate2 call from librbd to detect
> allocated and unallocated (all zero areas).
>
> To avoid querying the ceph OSDs for the answer this is only done if
> the image has the fast-diff feature which depends on the object-map and
> exclusive-lock features. In this case it is guaranteed that the information
> is present in memory in the librbd client and thus very fast.
>
> If fast-diff is not available all areas are reported to be allocated
> which is the current behaviour if bdrv_co_block_status is not implemented.
>
> Signed-off-by: Peter Lieven 
> ---
>  block/rbd.c | 112 
>  1 file changed, 112 insertions(+)
>
> V4->V5:
>  - rename rbd_diff_req to RBDDiffIterateReq, use typedef and move
>defintion to top [Ilya]
>  - rename callback to qemu_rbd_diff_iterate_cb [Ilya]
>  - assert that req.bytes == 0 if !req.exists and r == 0 [Ilya]
>
> V3->V4:
>  - make req.exists a bool [Ilya]
>  - simplify callback under the assuption that we never receive a cb
>for a hole since we do not diff against a snapshot [Ilya]
>  - remove out label [Ilya]
>  - rename ret to status [Ilya]
>
> V2->V3:
> - check rbd_flags every time (they can change during runtime) [Ilya]
> - also check for fast-diff invalid flag [Ilya]
> - *map and *file cant be NULL [Ilya]
> - set ret = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID in case of an
>   unallocated area [Ilya]
> - typo: catched -> caught [Ilya]
> - changed wording about fast-diff, object-map and exclusive lock in
>   commit msg [Ilya]
>
> V1->V2:
> - add commit comment [Stefano]
> - use failed_post_open [Stefano]
> - remove redundant assert [Stefano]
> - add macro+comment for the magic -9000 value [Stefano]
> - always set *file if its non NULL [Stefano]
>
>
> diff --git a/block/rbd.c b/block/rbd.c
> index 701fbf2b0c..def96292e0 100644
> --- a/block/rbd.c
> +++ b/block/rbd.c
> @@ -97,6 +97,12 @@ typedef struct RBDTask {
>  int64_t ret;
>  } RBDTask;
>
> +typedef struct RBDDiffIterateReq {
> +uint64_t offs;
> +uint64_t bytes;
> +bool exists;
> +} RBDDiffIterateReq;
> +
>  static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
>  BlockdevOptionsRbd *opts, bool cache,
>  const char *keypairs, const char *secretid,
> @@ -1259,6 +1265,111 @@ static ImageInfoSpecific 
> *qemu_rbd_get_specific_info(BlockDriverState *bs,
>  return spec_info;
>  }
>
> +/*
> + * rbd_diff_iterate2 allows to interrupt the exection by returning a negative
> + * value in the callback routine. Choose a value that does not conflict with
> + * an existing exitcode and return it if we want to prematurely stop the
> + * execution because we detected a change in the allocation status.
> + */
> +#define QEMU_RBD_EXIT_DIFF_ITERATE2 -9000
> +
> +static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
> +int exists, void *opaque)
> +{
> +RBDDiffIterateReq *req = opaque;
> +
> +assert(req->offs + req->bytes <= offs);
> +/*
> + * we do not diff against a snapshot so we should never receive a 
> callback
> + * for a hole.
> + */
> +assert(exists);
> +
> +if (!req->exists && offs > req->offs) {
> +/*
> + * we started in an unallocated area and hit the first allocated
> + * block. req->bytes must be set to the length of the unallocated 
> area
> + * before the allocated area. stop further processing.
> + */
> +req->bytes = offs - req->offs;
> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
> +}
> +
> +if (req->exists && offs > req->offs + req->bytes) {
> +/*
> + * we started in an allocated area and jumped over an unallocated 
> area,
> + * req->bytes contains the length of the allocated area before the
> + * unallocated area. stop further processing.
> + */
> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
> +}
> +
> +req->bytes += len;
> +req->exists = true;
> +
> +return 0;
> +}
> +
> +static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
> + bool want_zero, int64_t 
> offset,
> + int64_t bytes, int64_t 
> *pnum,
> + int64_t *map,
> + BlockDriverState **file)
> +{
> +BDRVRBDState *s = bs->opaque;
> +int status, r;
> +RBDDiffIterateReq req = { .offs = offset };
> +uint64_t features, flags;
> +
> +assert(offset + bytes <= s->image_size);
> +
> +/* default to all sectors allocated */
> +status =

Re: [PATCH 8/8] q800: add NMI handler

2021-10-17 Thread Laurent Vivier
Le 17/10/2021 à 12:00, Mark Cave-Ayland a écrit :
...
> I've just tried this on Linux, and it seems to work okay although I get 
> several copies of the
> register dump on the console for a single invocation of "info nmi" e.g.
> 
> [    4.61] Non-Maskable Interrupt
> [    4.61] Modules linked in: mac_esp(+) esp_scsi macsonic
> [    4.61] PC: [<2dc0>] arch_cpu_idle+0x4/0x6
> [    4.61] SR: 2000  SP: (ptrval)  a2: 00395314
> [    4.61] d0:     d1: 0002    d2: 0004b492    d3: 00392000
> [    4.61] d4:     d5:     a0: 00392000    a1: 00395314
> [    4.61] Process swapper (pid: 0, task=(ptrval))
> [    4.61] Frame format=0
> [    4.61] Stack from 00393f9c:
> [    4.61] 0004b540 0431 0040ee22 0004b4c4 0002bf6a 004005f0 
> 00393ff8 0004b714
> [    4.61] 0003e23a 0029c518 00c2 0040eb54 3dc1e5d0  
> 0004ff74 0003efe2
> [    4.61] 003f4e92  0040    
> 0040ee22 
> [    4.61] 003f3872
> [    4.61] Call Trace: [<0004b540>] do_idle+0x7c/0xd2
> [    4.61]  [<0004b4c4>] do_idle+0x0/0xd2
> [    4.61]  [<0002bf6a>] kernel_thread+0x0/0x26
> [    4.61]  [<004005f0>] __alloc_bootmem+0x0/0x38
> [    4.61]  [<0004b714>] cpu_startup_entry+0xe/0x12
> [    4.61]  [<0003e23a>] find_task_by_pid_ns+0x0/0x22
> [    4.61]  [<0029c518>] rest_init+0x78/0x82
> [    4.61]  [<0004ff74>] printk+0x0/0x18
> [    4.61]  [<0003efe2>] parse_args+0x0/0x2c2
> [    4.61]  [<003f4e92>] start_kernel+0x43e/0x448
> [    4.61]  [<003f3872>] _sinittext+0x872/0x11f8
> [    4.61] Code: bc00 0060 f210 f0ff 7001 60cc 4e72 2000 <4e75> 2079 003b 
> fc6c 4a88 6702 4e90
> 60fe 2079 003b fc68 4a88 6702 4e90 60fe 2f0c
> 
> (repeated 7 or 8 times)
> 
> MacsBug seems to handle this better: as soon as the NMI is triggered, MacsBug 
> opens and displays
> "NMI" both if the programmer switch GPIO is held active, or pulsed as 
> implemented in the patch. When
> using the above patch, subsequent NMI triggers do not display "NMI" or change 
> MacsBug in any visible
> way which suggests that once the NMI is triggered, the NMI is ignored until 
> the programmers switch
> GPIO is inactive once again.
> 
> Do you see the repeated register output in Linux for a single press of the 
> programmers switch on a
> real Quadra 800? It may be that Linux could be improved by having similar 
> logic.

In fact, register output is repeated while I keep the button pressed (5.14 
kernel provided by Finn)

If I press and release one (or several) time(s) before the end of the first 
output I have only one
output.

Thanks,
Laurent



Re: [PATCH v13 6/7] [RISCV_PM] Implement address masking functions required for RISC-V Pointer Masking extension

2021-10-17 Thread Alexey Baturo
Hi Richard,

Thanks for the review.

>Merge error.
fixed

>You might as well place the function correctly in the previous patch.
>Drop the silly alignment of parameters.
fixed

> int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
fixed

>priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
fixed

сб, 16 окт. 2021 г. в 03:01, Richard Henderson :

> On 10/15/21 12:29 PM, Alexey Baturo wrote:
> >   FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
> > +/* If PointerMasking should be applied */
> > +FIELD(TB_FLAGS, PM_ENABLED, 10, 1)
>
> Merge error.
>
> > +if (riscv_has_ext(env, RVJ)) {
> > +int priv = cpu_mmu_index(env, false) & TB_FLAGS_PRIV_MMU_MASK;
>
> cpu_mmu_index has already been computed.
> You want
>
>  int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
>
> > @@ -118,16 +125,6 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
> >  tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
> >  }
> >
> > -/*
> > - * Temp stub: generates address adjustment for PointerMasking
> > - */
> > -static void gen_pm_adjust_address(DisasContext *s,
> > -  TCGv *dst,
> > -  TCGv  src)
> > -{
> > -tcg_gen_mov_tl(*dst, src);
> > -}
> > -
>
> You might as well place the function correctly in the previous patch.
> Drop the silly alignment of parameters.
>
> > +int priv = cpu_mmu_index(env, false) & TB_FLAGS_PRIV_MMU_MASK;
> > +ctx->pm_mask = pm_mask[priv];
>
> Using cpu_mmu_index within the translator is incorrect.  You want
>
>  priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
>
>
> r~
>


Re: [PATCH v13 5/7] [RISCV_PM] Support pointer masking for RISC-V for i/c/f/d/a types of instructions

2021-10-17 Thread Alexey Baturo
Hi,

Sorry, my bad, got it wrong.
Fixed now.

Thanks!

сб, 16 окт. 2021 г. в 02:49, Richard Henderson :

> On 10/15/21 12:29 PM, Alexey Baturo wrote:
> > Signed-off-by: Alexey Baturo 
> > Reviewed-by: Richard Henderson 
> > Reviewed-by: Alistair Francis 
> > ---
> >   target/riscv/insn_trans/trans_rva.c.inc |  3 +++
> >   target/riscv/insn_trans/trans_rvd.c.inc |  2 ++
> >   target/riscv/insn_trans/trans_rvf.c.inc |  2 ++
> >   target/riscv/insn_trans/trans_rvi.c.inc |  2 ++
> >   target/riscv/translate.c| 10 ++
> >   5 files changed, 19 insertions(+)
> >
> > diff --git a/target/riscv/insn_trans/trans_rva.c.inc
> b/target/riscv/insn_trans/trans_rva.c.inc
> > index 6ea07d89b0..5bdc412191 100644
> > --- a/target/riscv/insn_trans/trans_rva.c.inc
> > +++ b/target/riscv/insn_trans/trans_rva.c.inc
> > @@ -25,6 +25,7 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a,
> MemOp mop)
> >   if (a->rl) {
> >   tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
> >   }
> > +gen_pm_adjust_address(ctx, &src1, src1);
> ...
> > +/*
> > + * Temp stub: generates address adjustment for PointerMasking
> > + */
> > +static void gen_pm_adjust_address(DisasContext *s,
> > +  TCGv *dst,
> > +  TCGv  src)
> > +{
> > +tcg_gen_mov_tl(*dst, src);
> > +}
>
> I mentioned before that you would not be able to do this.
> You are writing to the live cpu register, even if in this case it's a nop.
>
> You could, for example, make the stub be
>
>  *dst = src;
>
> but that begs the question of why not use the return value, and have the
> stub be
>
>  return src;
>
>
> r~
>


[PATCH v14 1/8] [RISCV_PM] Add J-extension into RISC-V

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 target/riscv/cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9e55b2f5b1..3f28dc5f3a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -67,6 +67,7 @@
 #define RVS RV('S')
 #define RVU RV('U')
 #define RVH RV('H')
+#define RVJ RV('J')
 
 /* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
@@ -289,6 +290,7 @@ struct RISCVCPU {
 bool ext_s;
 bool ext_u;
 bool ext_h;
+bool ext_j;
 bool ext_v;
 bool ext_zba;
 bool ext_zbb;
-- 
2.30.2




[PATCH v14 2/8] [RISCV_PM] Add CSR defines for RISC-V PM extension

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 96 +
 1 file changed, 96 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 999187a9ee..1a3767804a 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -334,6 +334,38 @@
 #define CSR_MHPMCOUNTER30H  0xb9e
 #define CSR_MHPMCOUNTER31H  0xb9f
 
+/*
+ * User PointerMasking registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_UMTE0x4c0
+#define CSR_UPMMASK 0x4c1
+#define CSR_UPMBASE 0x4c2
+
+/*
+ * Machine PointerMasking registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_MMTE0x3c0
+#define CSR_MPMMASK 0x3c1
+#define CSR_MPMBASE 0x3c2
+
+/*
+ * Supervisor PointerMaster registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_SMTE0x1c0
+#define CSR_SPMMASK 0x1c1
+#define CSR_SPMBASE 0x1c2
+
+/*
+ * Hypervisor PointerMaster registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_VSMTE   0x2c0
+#define CSR_VSPMMASK0x2c1
+#define CSR_VSPMBASE0x2c2
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -531,4 +563,68 @@ typedef enum RISCVException {
 #define MIE_UTIE   (1 << IRQ_U_TIMER)
 #define MIE_SSIE   (1 << IRQ_S_SOFT)
 #define MIE_USIE   (1 << IRQ_U_SOFT)
+
+/* General PointerMasking CSR bits*/
+#define PM_ENABLE   0x0001ULL
+#define PM_CURRENT  0x0002ULL
+#define PM_INSN 0x0004ULL
+#define PM_XS_MASK  0x0003ULL
+
+/* PointerMasking XS bits values */
+#define PM_EXT_DISABLE  0xULL
+#define PM_EXT_INITIAL  0x0001ULL
+#define PM_EXT_CLEAN0x0002ULL
+#define PM_EXT_DIRTY0x0003ULL
+
+/* Offsets for every pair of control bits per each priv level */
+#define XS_OFFSET0ULL
+#define U_OFFSET 2ULL
+#define S_OFFSET 5ULL
+#define M_OFFSET 8ULL
+
+#define PM_XS_BITS   (PM_XS_MASK << XS_OFFSET)
+#define U_PM_ENABLE  (PM_ENABLE  << U_OFFSET)
+#define U_PM_CURRENT (PM_CURRENT << U_OFFSET)
+#define U_PM_INSN(PM_INSN<< U_OFFSET)
+#define S_PM_ENABLE  (PM_ENABLE  << S_OFFSET)
+#define S_PM_CURRENT (PM_CURRENT << S_OFFSET)
+#define S_PM_INSN(PM_INSN<< S_OFFSET)
+#define M_PM_ENABLE  (PM_ENABLE  << M_OFFSET)
+#define M_PM_CURRENT (PM_CURRENT << M_OFFSET)
+#define M_PM_INSN(PM_INSN<< M_OFFSET)
+
+/* mmte CSR bits */
+#define MMTE_PM_XS_BITS PM_XS_BITS
+#define MMTE_U_PM_ENABLEU_PM_ENABLE
+#define MMTE_U_PM_CURRENT   U_PM_CURRENT
+#define MMTE_U_PM_INSN  U_PM_INSN
+#define MMTE_S_PM_ENABLES_PM_ENABLE
+#define MMTE_S_PM_CURRENT   S_PM_CURRENT
+#define MMTE_S_PM_INSN  S_PM_INSN
+#define MMTE_M_PM_ENABLEM_PM_ENABLE
+#define MMTE_M_PM_CURRENT   M_PM_CURRENT
+#define MMTE_M_PM_INSN  M_PM_INSN
+#define MMTE_MASK(MMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | MMTE_U_PM_INSN | \
+  MMTE_S_PM_ENABLE | MMTE_S_PM_CURRENT | MMTE_S_PM_INSN | \
+  MMTE_M_PM_ENABLE | MMTE_M_PM_CURRENT | MMTE_M_PM_INSN | \
+  MMTE_PM_XS_BITS)
+
+/* (v)smte CSR bits */
+#define SMTE_PM_XS_BITS PM_XS_BITS
+#define SMTE_U_PM_ENABLEU_PM_ENABLE
+#define SMTE_U_PM_CURRENT   U_PM_CURRENT
+#define SMTE_U_PM_INSN  U_PM_INSN
+#define SMTE_S_PM_ENABLES_PM_ENABLE
+#define SMTE_S_PM_CURRENT   S_PM_CURRENT
+#define SMTE_S_PM_INSN  S_PM_INSN
+#define SMTE_MASK(SMTE_U_PM_ENABLE | SMTE_U_PM_CURRENT | SMTE_U_PM_INSN | \
+  SMTE_S_PM_ENABLE | SMTE_S_PM_CURRENT | SMTE_S_PM_INSN | \
+  SMTE_PM_XS_BITS)
+
+/* umte CSR bits */
+#define UMTE_U_PM_ENABLEU_PM_ENABLE
+#define UMTE_U_PM_CURRENT   U_PM_CURRENT
+#define UMTE_U_PM_INSN  U_PM_INSN
+#define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN)
+
 #endif
-- 
2.30.2




[PATCH v14 5/8] [RISCV_PM] Print new PM CSRs in QEMU logs

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 75e8b8ca83..7f9dde70b7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -295,6 +295,31 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
int flags)
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mscratch", env->mscratch);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sscratch", env->sscratch);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "satp", env->satp);
+if (riscv_has_ext(env, RVJ)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mmte", env->mmte);
+switch (env->priv) {
+case PRV_U:
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "upmbase ",
+ env->upmbase);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "upmmask ",
+ env->upmmask);
+break;
+case PRV_S:
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "spmbase ",
+ env->spmbase);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "spmmask ",
+ env->spmmask);
+break;
+case PRV_M:
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mpmbase ",
+ env->mpmbase);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mpmmask ",
+ env->mpmmask);
+break;
+default:
+g_assert_not_reached();
+}
+}
 #endif
 
 for (i = 0; i < 32; i++) {
-- 
2.30.2




[PATCH v14 0/8] RISC-V Pointer Masking implementation

2021-10-17 Thread Alexey Baturo
v13:
Rebased QEMU and addressed Richard's comment.

v12:
Updated function for adjusting address with pointer masking to allocate and use 
temp register.

v11:
Addressed a few style issues Alistair mentioned in the previous review.

If this patch series would be accepted, I think my further attention would be 
to:
- Support pm for memory operations for RVV
- Add proper csr and support pm for memory operations for Hypervisor mode
- Support address wrapping on unaligned accesses as @Richard mentioned 
previously

Thanks!

Alexey Baturo (7):
  [RISCV_PM] Add J-extension into RISC-V
  [RISCV_PM] Add CSR defines for RISC-V PM extension
  [RISCV_PM] Support CSRs required for RISC-V PM extension except for
the h-mode
  [RISCV_PM] Add J extension state description
  [RISCV_PM] Print new PM CSRs in QEMU logs
  [RISCV_PM] Support pointer masking for RISC-V for i/c/f/d/a types of
instructions
  [RISCV_PM] Allow experimental J-ext to be turned on

Anatoly Parshintsev (1):
  [RISCV_PM] Implement address masking functions required for RISC-V
Pointer Masking extension

 target/riscv/cpu.c  |  31 +++
 target/riscv/cpu.h  |  33 +++
 target/riscv/cpu_bits.h |  96 
 target/riscv/csr.c  | 285 
 target/riscv/insn_trans/trans_rva.c.inc |   3 +
 target/riscv/insn_trans/trans_rvd.c.inc |   2 +
 target/riscv/insn_trans/trans_rvf.c.inc |   2 +
 target/riscv/insn_trans/trans_rvi.c.inc |   2 +
 target/riscv/machine.c  |  27 +++
 target/riscv/translate.c|  43 
 10 files changed, 524 insertions(+)

-- 
2.30.2




[PATCH v14 6/8] [RISCV_PM] Support pointer masking for RISC-V for i/c/f/d/a types of instructions

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rva.c.inc | 3 +++
 target/riscv/insn_trans/trans_rvd.c.inc | 2 ++
 target/riscv/insn_trans/trans_rvf.c.inc | 2 ++
 target/riscv/insn_trans/trans_rvi.c.inc | 2 ++
 target/riscv/translate.c| 8 
 5 files changed, 17 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
b/target/riscv/insn_trans/trans_rva.c.inc
index 6ea07d89b0..40fe132b04 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -25,6 +25,7 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 if (a->rl) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
 }
+src1 = gen_pm_adjust_address(ctx, src1);
 tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
 if (a->aq) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -44,6 +45,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 TCGLabel *l2 = gen_new_label();
 
 src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+src1 = gen_pm_adjust_address(ctx, src1);
 tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
 /*
@@ -84,6 +86,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 
+src1 = gen_pm_adjust_address(ctx, src1);
 func(dest, src1, src2, ctx->mem_idx, mop);
 
 gen_set_gpr(ctx, a->rd, dest);
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index db9ae15755..64fb0046f7 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
 
@@ -51,6 +52,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
 
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index bddbd418d9..b5459249c4 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -37,6 +37,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 dest = cpu_fpr[a->rd];
 tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
@@ -59,6 +60,7 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index a6a57c94bb..8690c977d5 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -144,6 +144,7 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp 
memop)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
 gen_set_gpr(ctx, a->rd, dest);
@@ -185,6 +186,7 @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp 
memop)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
 return true;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6d7fbca1fa..9e176b8137 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -247,6 +247,14 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
+/*
+ * Temp stub: generates address adjustment for PointerMasking
+ */
+static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
+{
+return src;
+}
+
 #ifndef CONFIG_USER_ONLY
 /* The states of mstatus_fs are:
  * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
-- 
2.30.2




[PATCH v14 3/8] [RISCV_PM] Support CSRs required for RISC-V PM extension except for the h-mode

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
---
 target/riscv/cpu.c |   2 +
 target/riscv/cpu.h |  11 ++
 target/riscv/csr.c | 285 +
 3 files changed, 298 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1d69d1887e..75e8b8ca83 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -365,6 +365,8 @@ static void riscv_cpu_reset(DeviceState *dev)
 env->mcause = 0;
 env->pc = env->resetvec;
 env->two_stage_lookup = false;
+/* mmte is supposed to have pm.current hardwired to 1 */
+env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
 cs->exception_index = RISCV_EXCP_NONE;
 env->load_res = -1;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3f28dc5f3a..acb4ce9d23 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -236,6 +236,17 @@ struct CPURISCVState {
 
 /* True if in debugger mode.  */
 bool debugger;
+
+/*
+ * CSRs for PointerMasking extension
+ */
+target_ulong mmte;
+target_ulong mpmmask;
+target_ulong mpmbase;
+target_ulong spmmask;
+target_ulong spmbase;
+target_ulong upmmask;
+target_ulong upmbase;
 #endif
 
 float_status fp_status;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd3216..d563289d37 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int 
csrno)
 
 }
 
+/* Checks if PointerMasking registers could be accessed */
+static RISCVException pointer_masking(CPURISCVState *env, int csrno)
+{
+/* Check if j-ext is present */
+if (riscv_has_ext(env, RVJ)) {
+return RISCV_EXCP_NONE;
+}
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 static RISCVException pmp(CPURISCVState *env, int csrno)
 {
 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
@@ -1401,6 +1411,268 @@ static RISCVException write_pmpaddr(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+/*
+ * Functions to access Pointer Masking feature registers
+ * We have to check if current priv lvl could modify
+ * csr in given mode
+ */
+static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
+{
+int csr_priv = get_field(csrno, 0x300);
+int pm_current;
+
+/*
+ * If priv lvls differ that means we're accessing csr from higher priv lvl,
+ * so allow the access
+ */
+if (env->priv != csr_priv) {
+return false;
+}
+switch (env->priv) {
+case PRV_M:
+pm_current = get_field(env->mmte, M_PM_CURRENT);
+break;
+case PRV_S:
+pm_current = get_field(env->mmte, S_PM_CURRENT);
+break;
+case PRV_U:
+pm_current = get_field(env->mmte, U_PM_CURRENT);
+break;
+default:
+g_assert_not_reached();
+}
+/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
+return !pm_current;
+}
+
+static RISCVException read_mmte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & MMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mmte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+uint64_t mstatus;
+target_ulong wpri_val = val & MMTE_MASK;
+
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "MMTE: WPRI violation written 0x%lx vs expected 0x%lx\n",
+  val, wpri_val);
+}
+/* for machine mode pm.current is hardwired to 1 */
+wpri_val |= MMTE_M_PM_CURRENT;
+
+/* hardwiring pm.instruction bit to 0, since it's not supported yet */
+wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
+env->mmte = wpri_val | PM_EXT_DIRTY;
+
+/* Set XS and SD bits, since PM CSRs are dirty */
+mstatus = env->mstatus | MSTATUS_XS;
+write_mstatus(env, csrno, mstatus);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_smte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & SMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_smte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+target_ulong wpri_val = val & SMTE_MASK;
+
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "SMTE: WPRI violation written 0x%lx vs expected 0x%lx\n",
+  val, wpri_val);
+}
+
+/* if pm.current==0 we can't modify current PM CSRs */
+if (check_pm_current_disabled(env, csrno)) {
+return RISCV_EXCP_NONE;
+}
+
+wpri_val |= (env->mmte & ~SMTE_MASK);
+write_mmte(env, csrno, wpri_val);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_umte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & UMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_umte(CPURISCVState *env

[PATCH v14 7/8] [RISCV_PM] Implement address masking functions required for RISC-V Pointer Masking extension

2021-10-17 Thread Alexey Baturo
From: Anatoly Parshintsev 

Signed-off-by: Anatoly Parshintsev 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   | 20 
 target/riscv/translate.c | 39 +--
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index acb4ce9d23..0ae12b9e61 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -407,6 +407,8 @@ FIELD(TB_FLAGS, VILL, 8, 1)
 /* Is a Hypervisor instruction load/store allowed? */
 FIELD(TB_FLAGS, HLSX, 9, 1)
 FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
+/* If PointerMasking should be applied */
+FIELD(TB_FLAGS, PM_ENABLED, 10, 1)
 
 bool riscv_cpu_is_32bit(CPURISCVState *env);
 
@@ -467,6 +469,24 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
get_field(env->mstatus_hs, MSTATUS_FS));
 }
+if (riscv_has_ext(env, RVJ)) {
+int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
+bool pm_enabled = false;
+switch (priv) {
+case PRV_U:
+pm_enabled = env->mmte & U_PM_ENABLE;
+break;
+case PRV_S:
+pm_enabled = env->mmte & S_PM_ENABLE;
+break;
+case PRV_M:
+pm_enabled = env->mmte & M_PM_ENABLE;
+break;
+default:
+g_assert_not_reached();
+}
+flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
+}
 #endif
 
 *pflags = flags;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9e176b8137..e1a5725395 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -36,6 +36,9 @@ static TCGv cpu_gpr[32], cpu_pc, cpu_vl;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
+/* globals for PM CSRs */
+static TCGv pm_mask[4];
+static TCGv pm_base[4];
 
 #include "exec/gen-icount.h"
 
@@ -82,6 +85,10 @@ typedef struct DisasContext {
 TCGv zero;
 /* Space for 3 operands plus 1 extra for address computation. */
 TCGv temp[4];
+/* PointerMasking extension */
+bool pm_enabled;
+TCGv pm_mask;
+TCGv pm_base;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -248,11 +255,20 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 }
 
 /*
- * Temp stub: generates address adjustment for PointerMasking
+ * Generates address adjustment for PointerMasking
  */
 static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
 {
-return src;
+TCGv temp;
+if (!s->pm_enabled) {
+/* Load unmodified address */
+return src;
+} else {
+temp = temp_new(s);
+tcg_gen_andc_tl(temp, src, s->pm_mask);
+tcg_gen_or_tl(temp, temp, s->pm_base);
+return temp;
+}
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -536,6 +552,10 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->w = false;
 ctx->ntemp = 0;
 memset(ctx->temp, 0, sizeof(ctx->temp));
+ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
+int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
+ctx->pm_mask = pm_mask[priv];
+ctx->pm_base = pm_base[priv];
 
 ctx->zero = tcg_constant_tl(0);
 }
@@ -649,4 +669,19 @@ void riscv_translate_init(void)
  "load_res");
 load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
  "load_val");
+#ifndef CONFIG_USER_ONLY
+/* Assign PM CSRs to tcg globals */
+pm_mask[PRV_U] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
+pm_base[PRV_U] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
+pm_mask[PRV_S] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
+pm_base[PRV_S] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
+pm_mask[PRV_M] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
+pm_base[PRV_M] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
+#endif
 }
-- 
2.30.2




[PATCH v14 8/8] [RISCV_PM] Allow experimental J-ext to be turned on

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7f9dde70b7..fb08c0ffb8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -558,6 +558,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 set_vext_version(env, vext_version);
 }
+if (cpu->cfg.ext_j) {
+target_misa |= RVJ;
+}
 
 set_misa(env, target_misa);
 }
@@ -624,6 +627,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false),
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
+DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
-- 
2.30.2




[PATCH v14 4/8] [RISCV_PM] Add J extension state description

2021-10-17 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
---
 target/riscv/machine.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 16a08302da..4d99880797 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -84,6 +84,14 @@ static bool vector_needed(void *opaque)
 return riscv_has_ext(env, RVV);
 }
 
+static bool pointermasking_needed(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = &cpu->env;
+
+return riscv_has_ext(env, RVJ);
+}
+
 static const VMStateDescription vmstate_vector = {
 .name = "cpu/vector",
 .version_id = 1,
@@ -138,6 +146,24 @@ static const VMStateDescription vmstate_hyper = {
 }
 };
 
+static const VMStateDescription vmstate_pointermasking = {
+.name = "cpu/pm",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = pointermasking_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(env.mmte, RISCVCPU),
+VMSTATE_UINTTL(env.mpmmask, RISCVCPU),
+VMSTATE_UINTTL(env.mpmbase, RISCVCPU),
+VMSTATE_UINTTL(env.spmmask, RISCVCPU),
+VMSTATE_UINTTL(env.spmbase, RISCVCPU),
+VMSTATE_UINTTL(env.upmmask, RISCVCPU),
+VMSTATE_UINTTL(env.upmbase, RISCVCPU),
+
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
 .version_id = 2,
@@ -189,6 +215,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 &vmstate_pmp,
 &vmstate_hyper,
 &vmstate_vector,
+&vmstate_pointermasking,
 NULL
 }
 };
-- 
2.30.2




Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread BALATON Zoltan

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/15/21 03:06, BALATON Zoltan wrote:

Use via_isa_set_irq() which better encapsulates irq handling in the
vt82xx model and avoids using isa_get_irq() that has a comment saying
it should not be used.

Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 94cc2142c7..252d18f4ac 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -29,7 +29,7 @@
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
 #include "trace.h"

@@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }

-qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+via_isa_set_irq(pci_get_function_0(d), 14 + n, level);


Since pci_get_function_0() is expensive, we should cache
'PCIDevice *func0' in PCIIDEState, setting the pointer in
via_ide_realize(). Do you mind sending a follow-up patch?


I can do that but waiting for a decision on how to proceed. Will Gerd take 
my first series this is based on as is then this should be a separate 
series doing the clean up using pci_get_function_0 or should these two 
series be merged? I'd also squash setting user_creatable = false into this 
patch (and do similar for the usb one) unless you guys think it should be 
a separate patch?


Regards,
BALATON Zoltan

Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread BALATON Zoltan

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/15/21 03:06, BALATON Zoltan wrote:

Use via_isa_set_irq() which better encapsulates irq handling in the
vt82xx model and avoids using isa_get_irq() that has a comment saying
it should not be used.

Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 94cc2142c7..252d18f4ac 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -29,7 +29,7 @@
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
 #include "trace.h"

@@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }

-qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+via_isa_set_irq(pci_get_function_0(d), 14 + n, level);


Since pci_get_function_0() is expensive, we should cache
'PCIDevice *func0' in PCIIDEState, setting the pointer in
via_ide_realize(). Do you mind sending a follow-up patch?


On the other hand, IMO PCIIDEState should be about PCI IDE stuff so to 
keep this clean this would need subclassing it to VIAIDEState and put the 
func0 pointer there. But then we probably need to cast between VIAIDE and 
PCIIDE and likely we're back to the same level of expensiveness. The main 
source why of pci_get_function_0 is expensive is probably the QOM cast to 
PCI_BUS in pci_get_bus() the rest is just pointer and array index 
dereferences which should not be too bad. And the reason why QOM casts are 
expensive is because we have --enable-qom-debug enabled by default. I've 
tried to send a patch before to disable this on release builds and only 
enable it with --enable-debug or when explicitly asked but it was rejected 
saying that these asserts are useful. Maybe we can just live with 
qemu_set_irq and not bother and drop this series. (You can cherry pick the 
first patch removing code duplication from via isa if you want.)


Regards,
BALATON Zoltan

Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/17/21 21:39, BALATON Zoltan wrote:
> On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:
>> On 10/15/21 03:06, BALATON Zoltan wrote:
>>> Use via_isa_set_irq() which better encapsulates irq handling in the
>>> vt82xx model and avoids using isa_get_irq() that has a comment saying
>>> it should not be used.
>>>
>>> Signed-off-by: BALATON Zoltan 
>>> ---
>>>  hw/ide/via.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>>> index 94cc2142c7..252d18f4ac 100644
>>> --- a/hw/ide/via.c
>>> +++ b/hw/ide/via.c
>>> @@ -29,7 +29,7 @@
>>>  #include "migration/vmstate.h"
>>>  #include "qemu/module.h"
>>>  #include "sysemu/dma.h"
>>> -
>>> +#include "hw/isa/vt82c686.h"
>>>  #include "hw/ide/pci.h"
>>>  #include "trace.h"
>>>
>>> @@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n,
>>> int level)
>>>  d->config[0x70 + n * 8] &= ~0x80;
>>>  }
>>>
>>> -    qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
>>> +    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
>>
>> Since pci_get_function_0() is expensive, we should cache
>> 'PCIDevice *func0' in PCIIDEState, setting the pointer in
>> via_ide_realize(). Do you mind sending a follow-up patch?
> 
> On the other hand, IMO PCIIDEState should be about PCI IDE stuff so to
> keep this clean this would need subclassing it to VIAIDEState and put
> the func0 pointer there.

I expect any multi-function PCI embedding an IDE controller to route
its IRQs via Func#0, but I'm not a PCI expert.

> But then we probably need to cast between
> VIAIDE and PCIIDE and likely we're back to the same level of
> expensiveness.

realize() is called once, get_irq() multiple times.

> The main source why of pci_get_function_0 is expensive is
> probably the QOM cast to PCI_BUS in pci_get_bus() the rest is just
> pointer and array index dereferences which should not be too bad. And
> the reason why QOM casts are expensive is because we have
> --enable-qom-debug enabled by default. I've tried to send a patch before
> to disable this on release builds and only enable it with --enable-debug
> or when explicitly asked but it was rejected saying that these asserts
> are useful. Maybe we can just live with qemu_set_irq and not bother and
> drop this series. (You can cherry pick the first patch removing code
> duplication from via isa if you want.)
> 
> Regards,
> BALATON Zoltan



Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread Philippe Mathieu-Daudé
On 10/17/21 20:44, BALATON Zoltan wrote:
> On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:
>> On 10/15/21 03:06, BALATON Zoltan wrote:
>>> Use via_isa_set_irq() which better encapsulates irq handling in the
>>> vt82xx model and avoids using isa_get_irq() that has a comment saying
>>> it should not be used.
>>>
>>> Signed-off-by: BALATON Zoltan 
>>> ---
>>>  hw/ide/via.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>>> index 94cc2142c7..252d18f4ac 100644
>>> --- a/hw/ide/via.c
>>> +++ b/hw/ide/via.c
>>> @@ -29,7 +29,7 @@
>>>  #include "migration/vmstate.h"
>>>  #include "qemu/module.h"
>>>  #include "sysemu/dma.h"
>>> -
>>> +#include "hw/isa/vt82c686.h"
>>>  #include "hw/ide/pci.h"
>>>  #include "trace.h"
>>>
>>> @@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n,
>>> int level)
>>>  d->config[0x70 + n * 8] &= ~0x80;
>>>  }
>>>
>>> -    qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
>>> +    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
>>
>> Since pci_get_function_0() is expensive, we should cache
>> 'PCIDevice *func0' in PCIIDEState, setting the pointer in
>> via_ide_realize(). Do you mind sending a follow-up patch?
> 
> I can do that but waiting for a decision on how to proceed. Will Gerd
> take my first series this is based on as is then this should be a
> separate series doing the clean up using pci_get_function_0 or should
> these two series be merged? I'd also squash setting user_creatable =
> false into this patch (and do similar for the usb one) unless you guys
> think it should be a separate patch?

I don't know what Gerd will do with the USB patches.
Your VIA patches are orthogonal, so I'm queuing them (1, 2, 4
and extra user_creatable) via mips-next.



Re: [PATCH v3] target/riscv: fix VS interrupts forwarding to HS

2021-10-17 Thread Jose Martins
Hello Zhiwei and Alistair,

I noticed this patch did not make it upstream, contrarily to a couple
other patches I submitted around the same time. Is there something
else needed from my side to push this forward?

Best,
José

On Wed, 2 Jun 2021 at 20:14, Jose Martins  wrote:
>
> Hello Zhiwei and Alistair,
>
> I went for a middle-ground solution. I divided the patch into two: one
> fixes the vs interrupt forwarding to the hypervisor, the other removes
> the unnecessary force exception stuff. I just submitted the patch
> series. I hope it's ok with you.
>
> José
>
> On Fri, 28 May 2021 at 01:36, LIU Zhiwei  wrote:
> >
> >
> > On 5/28/21 6:34 AM, Alistair Francis wrote:
> > > On Sun, May 23, 2021 at 1:45 AM Jose Martins  
> > > wrote:
> > >> VS interrupts (2, 6, 10) were not correctly forwarded to hs-mode when
> > >> not delegated in hideleg (which was not being taken into account). This
> > >> was mainly because hs level sie was not always considered enabled when
> > >> it should. The spec states that "Interrupts for higher-privilege modes,
> > >> y>x, are always globally enabled regardless of the setting of the global
> > >> yIE bit for the higher-privilege mode." and also "For purposes of
> > >> interrupt global enables, HS-mode is considered more privileged than
> > >> VS-mode, and VS-mode is considered more privileged than VU-mode".
> > >>
> > >> These interrupts should be treated the same as any other kind of
> > >> exception. Therefore, there is no need to "force an hs exception" as the
> > >> current privilege level, the state of the global ie and of the
> > >> delegation registers should be enough to route the interrupt to the
> > >> appropriate privilege level in riscv_cpu_do_interrupt. Also, these
> > >> interrupts never target m-mode, which is  guaranteed by the hardwiring
> > >> of the corresponding bits in mideleg. The same is true for synchronous
> > >> exceptions, specifically, guest page faults which must be hardwired in
> > >> to zero hedeleg. As such the hs_force_except mechanism can be removed.
> > >>
> > >> Signed-off-by: Jose Martins 
> > > This looks right to me, but this was one of the most confusing parts
> > > of the implementation. I also don't think the patch is too long as
> > > it's mostly just deleting stuff.
> > >
> > > I don't fully understand your concerns Zhiwei, do you mind stating them 
> > > again?
> >
> > Hi Alistair,
> >
> > My main concern is the commit message is to complex.
> >
> > I also have a question why force hs exception in current code.
> > Then we can give a brief commit message.
> >
> > Best Regards,
> > Zhiwei
> >
> > >
> > > Alistair
> > >
> > >> ---
> > >> This version of the patch also removes the uneeded hs_force_except
> > >> functions, variables and macro.
> > >>
> > >>   target/riscv/cpu.h|  2 --
> > >>   target/riscv/cpu_bits.h   |  6 -
> > >>   target/riscv/cpu_helper.c | 54 +++
> > >>   3 files changed, 9 insertions(+), 53 deletions(-)
> > >>
> > >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > >> index 0a33d387ba..a30a64241a 100644
> > >> --- a/target/riscv/cpu.h
> > >> +++ b/target/riscv/cpu.h
> > >> @@ -337,8 +337,6 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
> > >> interrupt_request);
> > >>   bool riscv_cpu_fp_enabled(CPURISCVState *env);
> > >>   bool riscv_cpu_virt_enabled(CPURISCVState *env);
> > >>   void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
> > >> -bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
> > >> -void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
> > >>   bool riscv_cpu_two_stage_lookup(int mmu_idx);
> > >>   int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
> > >>   hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
> > >> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > >> index caf4599207..7322f54157 100644
> > >> --- a/target/riscv/cpu_bits.h
> > >> +++ b/target/riscv/cpu_bits.h
> > >> @@ -462,12 +462,6 @@
> > >>
> > >>   /* Virtulisation Register Fields */
> > >>   #define VIRT_ONOFF  1
> > >> -/* This is used to save state for when we take an exception. If this is 
> > >> set
> > >> - * that means that we want to force a HS level exception (no matter 
> > >> what the
> > >> - * delegation is set to). This will occur for things such as a second 
> > >> level
> > >> - * page table fault.
> > >> - */
> > >> -#define FORCE_HS_EXCEP  2
> > >>
> > >>   /* RV32 satp CSR field masks */
> > >>   #define SATP32_MODE 0x8000
> > >> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > >> index 21c54ef561..babe3d844b 100644
> > >> --- a/target/riscv/cpu_helper.c
> > >> +++ b/target/riscv/cpu_helper.c
> > >> @@ -38,36 +38,24 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool 
> > >> ifetch)
> > >>   #ifndef CONFIG_USER_ONLY
> > >>   static int riscv_cpu_local_irq_pending(CPURISCVState *env)
> > >>   {
> > >> -target_ulong irqs;
> > >> +  

Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread BALATON Zoltan

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/17/21 21:39, BALATON Zoltan wrote:

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/15/21 03:06, BALATON Zoltan wrote:

Use via_isa_set_irq() which better encapsulates irq handling in the
vt82xx model and avoids using isa_get_irq() that has a comment saying
it should not be used.

Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 94cc2142c7..252d18f4ac 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -29,7 +29,7 @@
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
 #include "trace.h"

@@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n,
int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }

-    qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);


Since pci_get_function_0() is expensive, we should cache
'PCIDevice *func0' in PCIIDEState, setting the pointer in
via_ide_realize(). Do you mind sending a follow-up patch?


On the other hand, IMO PCIIDEState should be about PCI IDE stuff so to
keep this clean this would need subclassing it to VIAIDEState and put
the func0 pointer there.


I expect any multi-function PCI embedding an IDE controller to route
its IRQs via Func#0, but I'm not a PCI expert.


We don't have many in QEMU, I think only via and piix and not sure what 
piix does (currently using isa_get_irq, that's where I got this from for 
via).



But then we probably need to cast between
VIAIDE and PCIIDE and likely we're back to the same level of
expensiveness.


realize() is called once, get_irq() multiple times.


Sure but we need to pass something to set_irq which will be then 
VIAIDEState that maybe we'll need to cast to something else but now we 
also cast it to PCI_DEVICE so maybe we could cache that too?


Regards,
BALATON Zoltan


The main source why of pci_get_function_0 is expensive is
probably the QOM cast to PCI_BUS in pci_get_bus() the rest is just
pointer and array index dereferences which should not be too bad. And
the reason why QOM casts are expensive is because we have
--enable-qom-debug enabled by default. I've tried to send a patch before
to disable this on release builds and only enable it with --enable-debug
or when explicitly asked but it was rejected saying that these asserts
are useful. Maybe we can just live with qemu_set_irq and not bother and
drop this series. (You can cherry pick the first patch removing code
duplication from via isa if you want.)

Regards,
BALATON Zoltan




Re: [PATCH 4/4] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread BALATON Zoltan

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/17/21 20:44, BALATON Zoltan wrote:

On Sun, 17 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/15/21 03:06, BALATON Zoltan wrote:

Use via_isa_set_irq() which better encapsulates irq handling in the
vt82xx model and avoids using isa_get_irq() that has a comment saying
it should not be used.

Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 94cc2142c7..252d18f4ac 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -29,7 +29,7 @@
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
 #include "trace.h"

@@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n,
int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }

-    qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);


Since pci_get_function_0() is expensive, we should cache
'PCIDevice *func0' in PCIIDEState, setting the pointer in
via_ide_realize(). Do you mind sending a follow-up patch?


I can do that but waiting for a decision on how to proceed. Will Gerd
take my first series this is based on as is then this should be a
separate series doing the clean up using pci_get_function_0 or should
these two series be merged? I'd also squash setting user_creatable =
false into this patch (and do similar for the usb one) unless you guys
think it should be a separate patch?


I don't know what Gerd will do with the USB patches.
Your VIA patches are orthogonal, so I'm queuing them (1, 2, 4
and extra user_creatable) via mips-next.


I'm confused. So you don't need another version from the last two at 
least? And patch 2 is useless without the rest of the series that's why I 
said you can cherry pick 1.


Regards,
BALATON Zoltan

[PULL 01/17] target/mips: Check nanoMIPS DSP MULT[U] accumulator with Release 6

2021-10-17 Thread Philippe Mathieu-Daudé
Per the "MIPS Architecture Extension: nanoMIPS32 DSP TRM" rev 0.04,
MULT and MULTU opcodes:

  The value of ac selects an accumulator numbered from 0 to 3.
  When ac=0, this refers to the original HI/LO register pair of the
  MIPS32 architecture.

  In Release 6 of the MIPS Architecture, accumulators are eliminated
  from MIPS32.

Ensure pre-Release 6 is restricted to HI/LO registers pair.

Fixes: 8b3698b2947 ("target/mips: Add emulation of DSP ASE for nanoMIPS - part 
4")
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/nanomips_translate.c.inc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/mips/tcg/nanomips_translate.c.inc 
b/target/mips/tcg/nanomips_translate.c.inc
index ccbcecad093..2c022a49f24 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -1868,6 +1868,9 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext 
*ctx, uint32_t opc,
 TCGv_i32 t2 = tcg_temp_new_i32();
 TCGv_i32 t3 = tcg_temp_new_i32();
 
+if (acc || ctx->insn_flags & ISA_MIPS_R6) {
+check_dsp_r2(ctx);
+}
 gen_load_gpr(t0, rs);
 gen_load_gpr(t1, rt);
 tcg_gen_trunc_tl_i32(t2, t0);
@@ -1925,6 +1928,9 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext 
*ctx, uint32_t opc,
 TCGv_i32 t2 = tcg_temp_new_i32();
 TCGv_i32 t3 = tcg_temp_new_i32();
 
+if (acc || ctx->insn_flags & ISA_MIPS_R6) {
+check_dsp_r2(ctx);
+}
 gen_load_gpr(t0, rs);
 gen_load_gpr(t1, rt);
 tcg_gen_trunc_tl_i32(t2, t0);
-- 
2.31.1




[PULL 03/17] hw/mips/boston: Allow loading elf kernel and dtb

2021-10-17 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

ELF kernel allows us debugging much easier with DWARF symbols.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
[PMD: Fix coding style]
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20211002184539.169-3-jiaxun.y...@flygoat.com>
---
 hw/mips/boston.c | 36 
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 37b8278623e..7374bb5da4d 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/units.h"
 
+#include "elf.h"
 #include "hw/boards.h"
 #include "hw/char/serial.h"
 #include "hw/ide/pci.h"
@@ -551,10 +552,37 @@ static void boston_mach_init(MachineState *machine)
 exit(1);
 }
 } else if (machine->kernel_filename) {
-fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
-if (fit_err) {
-error_report("unable to load FIT image");
-exit(1);
+uint64_t kernel_entry, kernel_high, kernel_size;
+
+kernel_size = load_elf(machine->kernel_filename, NULL,
+   cpu_mips_kseg0_to_phys, NULL,
+   &kernel_entry, NULL, &kernel_high,
+   NULL, 0, EM_MIPS, 1, 0);
+
+if (kernel_size) {
+hwaddr dtb_paddr = QEMU_ALIGN_UP(kernel_high, 64 * KiB);
+hwaddr dtb_vaddr = cpu_mips_phys_to_kseg0(NULL, dtb_paddr);
+
+s->kernel_entry = kernel_entry;
+if (machine->dtb) {
+int dt_size;
+g_autofree const void *dtb_file_data, *dtb_load_data;
+
+dtb_file_data = load_device_tree(machine->dtb, &dt_size);
+dtb_load_data = boston_fdt_filter(s, dtb_file_data,
+  NULL, &dtb_vaddr);
+
+/* Calculate real fdt size after filter */
+dt_size = fdt_totalsize(dtb_load_data);
+rom_add_blob_fixed("dtb", dtb_load_data, dt_size, dtb_paddr);
+}
+} else {
+/* Try to load file as FIT */
+fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, 
s);
+if (fit_err) {
+error_report("unable to load kernel image");
+exit(1);
+}
 }
 
 gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c0,
-- 
2.31.1




[PULL 02/17] hw/mips/boston: Massage memory map information

2021-10-17 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

Use memmap array to uinfy address of memory map.
That would allow us reuse address information for FDT generation.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
[PMD: Use local 'regaddr' in gen_firmware(), fix coding style]
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20211002184539.169-2-jiaxun.y...@flygoat.com>
---
 hw/mips/boston.c | 108 +++
 1 file changed, 80 insertions(+), 28 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 20b06865b2b..37b8278623e 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -64,6 +64,44 @@ struct BostonState {
 hwaddr fdt_base;
 };
 
+enum {
+BOSTON_LOWDDR,
+BOSTON_PCIE0,
+BOSTON_PCIE1,
+BOSTON_PCIE2,
+BOSTON_PCIE2_MMIO,
+BOSTON_CM,
+BOSTON_GIC,
+BOSTON_CDMM,
+BOSTON_CPC,
+BOSTON_PLATREG,
+BOSTON_UART,
+BOSTON_LCD,
+BOSTON_FLASH,
+BOSTON_PCIE1_MMIO,
+BOSTON_PCIE0_MMIO,
+BOSTON_HIGHDDR,
+};
+
+static const MemMapEntry boston_memmap[] = {
+[BOSTON_LOWDDR] = {0x0,0x1000 },
+[BOSTON_PCIE0] =  { 0x1000, 0x200 },
+[BOSTON_PCIE1] =  { 0x1200, 0x200 },
+[BOSTON_PCIE2] =  { 0x1400, 0x200 },
+[BOSTON_PCIE2_MMIO] = { 0x1600,  0x10 },
+[BOSTON_CM] = { 0x1610,   0x2 },
+[BOSTON_GIC] ={ 0x1612,   0x2 },
+[BOSTON_CDMM] =   { 0x1614,0x8000 },
+[BOSTON_CPC] ={ 0x1620,0x8000 },
+[BOSTON_PLATREG] ={ 0x17ffd000,0x1000 },
+[BOSTON_UART] =   { 0x17ffe000,  0x20 },
+[BOSTON_LCD] ={ 0x17fff000,   0x8 },
+[BOSTON_FLASH] =  { 0x1800, 0x800 },
+[BOSTON_PCIE1_MMIO] = { 0x2000,0x2000 },
+[BOSTON_PCIE0_MMIO] = { 0x4000,0x4000 },
+[BOSTON_HIGHDDR] ={ 0x8000,   0x0 },
+};
+
 enum boston_plat_reg {
 PLAT_FPGA_BUILD = 0x00,
 PLAT_CORE_CL= 0x04,
@@ -275,24 +313,24 @@ type_init(boston_register_types)
 
 static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr)
 {
-const uint32_t cm_base = 0x1610;
-const uint32_t gic_base = 0x1612;
-const uint32_t cpc_base = 0x1620;
+uint64_t regaddr;
 
 /* Move CM GCRs */
-bl_gen_write_ulong(&p,
-   cpu_mips_phys_to_kseg1(NULL, GCR_BASE_ADDR + 
GCR_BASE_OFS),
-   cm_base);
+regaddr = cpu_mips_phys_to_kseg1(NULL, GCR_BASE_ADDR + GCR_BASE_OFS),
+bl_gen_write_ulong(&p, regaddr,
+   boston_memmap[BOSTON_CM].base);
 
 /* Move & enable GIC GCRs */
-bl_gen_write_ulong(&p,
-   cpu_mips_phys_to_kseg1(NULL, cm_base + 
GCR_GIC_BASE_OFS),
-   gic_base | GCR_GIC_BASE_GICEN_MSK);
+regaddr = cpu_mips_phys_to_kseg1(NULL, boston_memmap[BOSTON_CM].base
+   + GCR_GIC_BASE_OFS),
+bl_gen_write_ulong(&p, regaddr,
+   boston_memmap[BOSTON_GIC].base | 
GCR_GIC_BASE_GICEN_MSK);
 
 /* Move & enable CPC GCRs */
-bl_gen_write_ulong(&p,
-   cpu_mips_phys_to_kseg1(NULL, cm_base + 
GCR_CPC_BASE_OFS),
-   cpc_base | GCR_CPC_BASE_CPCEN_MSK);
+regaddr = cpu_mips_phys_to_kseg1(NULL, boston_memmap[BOSTON_CM].base
+   + GCR_CPC_BASE_OFS),
+bl_gen_write_ulong(&p, regaddr,
+   boston_memmap[BOSTON_CPC].base | 
GCR_CPC_BASE_CPCEN_MSK);
 
 /*
  * Setup argument registers to follow the UHI boot protocol:
@@ -333,8 +371,9 @@ static const void *boston_fdt_filter(void *opaque, const 
void *fdt_orig,
 ram_low_sz = MIN(256 * MiB, machine->ram_size);
 ram_high_sz = machine->ram_size - ram_low_sz;
 qemu_fdt_setprop_sized_cells(fdt, "/memory@0", "reg",
- 1, 0x, 1, ram_low_sz,
- 1, 0x9000, 1, ram_high_sz);
+1, boston_memmap[BOSTON_LOWDDR].base, 1, ram_low_sz,
+1, boston_memmap[BOSTON_HIGHDDR].base + ram_low_sz,
+1, ram_high_sz);
 
 fdt = g_realloc(fdt, fdt_totalsize(fdt));
 qemu_fdt_dumpdtb(fdt, fdt_sz);
@@ -438,11 +477,15 @@ static void boston_mach_init(MachineState *machine)
 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->cps), 0, 0, 1);
 
 flash =  g_new(MemoryRegion, 1);
-memory_region_init_rom(flash, NULL, "boston.flash", 128 * MiB,
-   &error_fatal);
-memory_region_add_subregion_overlap(sys_mem, 0x1800, flash, 0);
+memory_region_init_rom(flash, NULL, "boston.flash",
+   boston_memmap[BOSTON_FLASH].size, &error_fatal);
+memory_region_add_subregion_overlap(sys_mem,
+boston_memmap[BOST

[PULL 06/17] target/mips: Use tcg_constant_i32() in gen_msa_elm_df()

2021-10-17 Thread Philippe Mathieu-Daudé
Data Format is a 2-bit constant value.
Avoid using a TCG temporary by moving it to the constant pool.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-3-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index ee6424126f7..20036ae4968 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -1650,7 +1650,7 @@ static void gen_msa_elm_df(DisasContext *ctx, uint32_t 
df, uint32_t n)
 TCGv_i32 tws = tcg_const_i32(ws);
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tn  = tcg_const_i32(n);
-TCGv_i32 tdf = tcg_const_i32(df);
+TCGv_i32 tdf = tcg_constant_i32(df);
 
 switch (MASK_MSA_ELM(ctx->opcode)) {
 case OPC_SLDI_df:
@@ -1748,7 +1748,6 @@ static void gen_msa_elm_df(DisasContext *ctx, uint32_t 
df, uint32_t n)
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
 tcg_temp_free_i32(tn);
-tcg_temp_free_i32(tdf);
 }
 
 static void gen_msa_elm(DisasContext *ctx)
-- 
2.31.1




[PULL 00/17] MIPS patches for 2021-10-18

2021-10-17 Thread Philippe Mathieu-Daudé
The following changes since commit c148a0572130ff485cd2249fbdd1a3260d5e10a4:

  Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20211016' into 
staging (2021-10-16 11:16:28 -0700)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/mips-20211018

for you to fetch changes up to 2792cf20ca7eed0e354a0ed731422411faca4908:

  via-ide: Avoid using isa_get_irq() (2021-10-18 00:41:36 +0200)


MIPS patches queue

Hardware emulation:
- Generate FDT blob for Boston machine (Jiaxun)
- VIA chipset cleanups (Zoltan)

TCG:
- Use tcg_constant() in Compact branch and MSA opcodes
- Restrict nanoMIPS DSP MULT[U] opcode accumulator to Rel6
- Fix DEXTRV_S.H DSP opcode
- Remove unused TCG temporary for some DSP opcodes



BALATON Zoltan (4):
  via-ide: Set user_creatable to false
  vt82c686: Move common code to via_isa_realize
  vt82c686: Add a method to VIA_ISA to raise ISA interrupts
  via-ide: Avoid using isa_get_irq()

Jiaxun Yang (3):
  hw/mips/boston: Massage memory map information
  hw/mips/boston: Allow loading elf kernel and dtb
  hw/mips/boston: Add FDT generator

Philippe Mathieu-Daudé (10):
  target/mips: Check nanoMIPS DSP MULT[U] accumulator with Release 6
  target/mips: Remove unused register from MSA 2R/2RF instruction format
  target/mips: Use tcg_constant_i32() in gen_msa_elm_df()
  target/mips: Use tcg_constant_i32() in gen_msa_2rf()
  target/mips: Use tcg_constant_i32() in gen_msa_2r()
  target/mips: Use tcg_constant_i32() in gen_msa_3rf()
  target/mips: Use explicit extract32() calls in gen_msa_i5()
  target/mips: Use tcg_constant_tl() in gen_compute_compact_branch()
  target/mips: Fix DEXTRV_S.H DSP opcode
  target/mips: Remove unused TCG temporary in gen_mipsdsp_accinsn()

 include/hw/isa/vt82c686.h|   4 +
 hw/ide/via.c |   7 +-
 hw/isa/vt82c686.c|  75 +++--
 hw/mips/boston.c | 371 +--
 target/mips/tcg/msa_translate.c  |  51 ++--
 target/mips/tcg/translate.c  |  11 +-
 target/mips/tcg/nanomips_translate.c.inc |   6 +
 7 files changed, 415 insertions(+), 110 deletions(-)

-- 
2.31.1




[PULL 04/17] hw/mips/boston: Add FDT generator

2021-10-17 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

Generate FDT on our own if no dtb argument supplied.
Avoid introducing unused device in FDT with user supplied dtb.

Signed-off-by: Jiaxun Yang 
[PMD: Fix coding style]
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20211002184539.169-4-jiaxun.y...@flygoat.com>
---
 hw/mips/boston.c | 245 +--
 1 file changed, 236 insertions(+), 9 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 7374bb5da4d..0e3cca55118 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -49,6 +49,15 @@ typedef struct BostonState BostonState;
 DECLARE_INSTANCE_CHECKER(BostonState, BOSTON,
  TYPE_BOSTON)
 
+#define FDT_IRQ_TYPE_NONE   0
+#define FDT_IRQ_TYPE_LEVEL_HIGH 4
+#define FDT_GIC_SHARED  0
+#define FDT_GIC_LOCAL   1
+#define FDT_BOSTON_CLK_SYS  1
+#define FDT_BOSTON_CLK_CPU  2
+#define FDT_PCI_IRQ_MAP_PINS4
+#define FDT_PCI_IRQ_MAP_DESCS   6
+
 struct BostonState {
 SysBusDevice parent_obj;
 
@@ -437,6 +446,222 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
 return XILINX_PCIE_HOST(dev);
 }
 
+
+static void fdt_create_pcie(void *fdt, int gic_ph, int irq, hwaddr reg_base,
+hwaddr reg_size, hwaddr mmio_base, hwaddr 
mmio_size)
+{
+int i;
+char *name, *intc_name;
+uint32_t intc_ph;
+uint32_t interrupt_map[FDT_PCI_IRQ_MAP_PINS][FDT_PCI_IRQ_MAP_DESCS];
+
+intc_ph = qemu_fdt_alloc_phandle(fdt);
+name = g_strdup_printf("/soc/pci@%" HWADDR_PRIx, reg_base);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop_string(fdt, name, "compatible",
+"xlnx,axi-pcie-host-1.00.a");
+qemu_fdt_setprop_string(fdt, name, "device_type", "pci");
+qemu_fdt_setprop_cells(fdt, name, "reg", reg_base, reg_size);
+
+qemu_fdt_setprop_cell(fdt, name, "#address-cells", 3);
+qemu_fdt_setprop_cell(fdt, name, "#size-cells", 2);
+qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 1);
+
+qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", gic_ph);
+qemu_fdt_setprop_cells(fdt, name, "interrupts", FDT_GIC_SHARED, irq,
+FDT_IRQ_TYPE_LEVEL_HIGH);
+
+qemu_fdt_setprop_cells(fdt, name, "ranges", 0x0200, 0, mmio_base,
+mmio_base, 0, mmio_size);
+qemu_fdt_setprop_cells(fdt, name, "bus-range", 0x00, 0xff);
+
+
+
+intc_name = g_strdup_printf("%s/interrupt-controller", name);
+qemu_fdt_add_subnode(fdt, intc_name);
+qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
+qemu_fdt_setprop_cell(fdt, intc_name, "#address-cells", 0);
+qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
+qemu_fdt_setprop_cell(fdt, intc_name, "phandle", intc_ph);
+
+qemu_fdt_setprop_cells(fdt, name, "interrupt-map-mask", 0, 0, 0, 7);
+for (i = 0; i < FDT_PCI_IRQ_MAP_PINS; i++) {
+uint32_t *irqmap = interrupt_map[i];
+
+irqmap[0] = cpu_to_be32(0);
+irqmap[1] = cpu_to_be32(0);
+irqmap[2] = cpu_to_be32(0);
+irqmap[3] = cpu_to_be32(i + 1);
+irqmap[4] = cpu_to_be32(intc_ph);
+irqmap[5] = cpu_to_be32(i + 1);
+}
+qemu_fdt_setprop(fdt, name, "interrupt-map",
+ &interrupt_map, sizeof(interrupt_map));
+
+g_free(intc_name);
+g_free(name);
+}
+
+static const void *create_fdt(BostonState *s,
+  const MemMapEntry *memmap, int *dt_size)
+{
+void *fdt;
+int cpu;
+MachineState *mc = s->mach;
+uint32_t platreg_ph, gic_ph, clk_ph;
+char *name, *gic_name, *platreg_name, *stdout_name;
+static const char * const syscon_compat[2] = {
+"img,boston-platform-regs", "syscon"
+};
+
+fdt = create_device_tree(dt_size);
+if (!fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+platreg_ph = qemu_fdt_alloc_phandle(fdt);
+gic_ph = qemu_fdt_alloc_phandle(fdt);
+clk_ph = qemu_fdt_alloc_phandle(fdt);
+
+qemu_fdt_setprop_string(fdt, "/", "model", "img,boston");
+qemu_fdt_setprop_string(fdt, "/", "compatible", "img,boston");
+qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
+qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x1);
+
+
+qemu_fdt_add_subnode(fdt, "/cpus");
+qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
+qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
+
+for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
+name = g_strdup_printf("/cpus/cpu@%d", cpu);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
+qemu_fdt_setprop_string(fdt, name, "status", "okay");
+qemu_fdt_setprop_cell(fdt, name, "reg", cpu);
+qemu_fdt_setprop_string(fdt, name, "device_type", "cpu");
+qemu_fdt_setprop_cells(fdt, name, "clocks", clk_ph, 
FDT_BOSTON_CLK_CPU);
+g_free(name);
+}
+
+qemu_

[PULL 05/17] target/mips: Remove unused register from MSA 2R/2RF instruction format

2021-10-17 Thread Philippe Mathieu-Daudé
Commits cbe50b9a8e7 ("target-mips: add MSA VEC/2R format instructions")
and 3bdeb68866e ("target-mips: add MSA 2RF format instructions") added
the MSA 2R/2RF instructions. However these instructions don't use any
target vector register, so remove the unused TCG temporaries.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20211003175743.3738710-2-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index 8170a8df26b..ee6424126f7 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -1942,13 +1942,11 @@ static void gen_msa_2r(DisasContext *ctx)
 {
 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
 (op & (0x7 << 18)))
-uint8_t wt = (ctx->opcode >> 16) & 0x1f;
 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
 uint8_t df = (ctx->opcode >> 16) & 0x3;
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tws = tcg_const_i32(ws);
-TCGv_i32 twt = tcg_const_i32(wt);
 TCGv_i32 tdf = tcg_const_i32(df);
 
 switch (MASK_MSA_2R(ctx->opcode)) {
@@ -2018,7 +2016,6 @@ static void gen_msa_2r(DisasContext *ctx)
 
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
-tcg_temp_free_i32(twt);
 tcg_temp_free_i32(tdf);
 }
 
@@ -2026,13 +2023,11 @@ static void gen_msa_2rf(DisasContext *ctx)
 {
 #define MASK_MSA_2RF(op)(MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
 (op & (0xf << 17)))
-uint8_t wt = (ctx->opcode >> 16) & 0x1f;
 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
 uint8_t df = (ctx->opcode >> 16) & 0x1;
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tws = tcg_const_i32(ws);
-TCGv_i32 twt = tcg_const_i32(wt);
 /* adjust df value for floating-point instruction */
 TCGv_i32 tdf = tcg_const_i32(df + 2);
 
@@ -2089,7 +2084,6 @@ static void gen_msa_2rf(DisasContext *ctx)
 
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
-tcg_temp_free_i32(twt);
 tcg_temp_free_i32(tdf);
 }
 
-- 
2.31.1




[PULL 11/17] target/mips: Use tcg_constant_tl() in gen_compute_compact_branch()

2021-10-17 Thread Philippe Mathieu-Daudé
The offset is constant and read-only: move it to the constant pool.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-9-f4...@amsat.org>
---
 target/mips/tcg/translate.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 0e59b97190f..5fdeb67e82b 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -11857,13 +11857,11 @@ static void gen_compute_compact_branch(DisasContext 
*ctx, uint32_t opc,
 } else {
 /* OPC_JIC, OPC_JIALC */
 TCGv tbase = tcg_temp_new();
-TCGv toffset = tcg_temp_new();
+TCGv toffset = tcg_constant_tl(offset);
 
 gen_load_gpr(tbase, rt);
-tcg_gen_movi_tl(toffset, offset);
 gen_op_addr_add(ctx, btarget, tbase, toffset);
 tcg_temp_free(tbase);
-tcg_temp_free(toffset);
 }
 break;
 default:
-- 
2.31.1




[PULL 10/17] target/mips: Use explicit extract32() calls in gen_msa_i5()

2021-10-17 Thread Philippe Mathieu-Daudé
We already use sextract32(), use extract32() for completeness
instead of open-coding it.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-7-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index e107cad57ee..3ef912da6b8 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -473,15 +473,12 @@ static void gen_msa_i8(DisasContext *ctx)
 static void gen_msa_i5(DisasContext *ctx)
 {
 #define MASK_MSA_I5(op)(MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
-uint8_t df = (ctx->opcode >> 21) & 0x3;
 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
-uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
-uint8_t ws = (ctx->opcode >> 11) & 0x1f;
-uint8_t wd = (ctx->opcode >> 6) & 0x1f;
+uint8_t u5 = extract32(ctx->opcode, 16, 5);
 
-TCGv_i32 tdf = tcg_const_i32(df);
-TCGv_i32 twd = tcg_const_i32(wd);
-TCGv_i32 tws = tcg_const_i32(ws);
+TCGv_i32 tdf = tcg_const_i32(extract32(ctx->opcode, 21, 2));
+TCGv_i32 twd = tcg_const_i32(extract32(ctx->opcode, 11, 5));
+TCGv_i32 tws = tcg_const_i32(extract32(ctx->opcode, 6, 5));
 TCGv_i32 timm = tcg_temp_new_i32();
 tcg_gen_movi_i32(timm, u5);
 
-- 
2.31.1




[PULL 07/17] target/mips: Use tcg_constant_i32() in gen_msa_2rf()

2021-10-17 Thread Philippe Mathieu-Daudé
Avoid using a TCG temporary by moving Data Format to the constant pool.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-4-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index 20036ae4968..5e8f80f2f23 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -2028,7 +2028,7 @@ static void gen_msa_2rf(DisasContext *ctx)
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tws = tcg_const_i32(ws);
 /* adjust df value for floating-point instruction */
-TCGv_i32 tdf = tcg_const_i32(df + 2);
+TCGv_i32 tdf = tcg_constant_i32(df + 2);
 
 switch (MASK_MSA_2RF(ctx->opcode)) {
 case OPC_FCLASS_df:
@@ -2083,7 +2083,6 @@ static void gen_msa_2rf(DisasContext *ctx)
 
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
-tcg_temp_free_i32(tdf);
 }
 
 static void gen_msa_vec_v(DisasContext *ctx)
-- 
2.31.1




[PULL 13/17] target/mips: Remove unused TCG temporary in gen_mipsdsp_accinsn()

2021-10-17 Thread Philippe Mathieu-Daudé
Since gen_mipsdsp_accinsn() got added in commit b53371ed5d4
("target-mips: Add ASE DSP accumulator instructions"), the
'v2_t' TCG temporary has never been used. Remove it.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211014224551.2204949-1-f4...@amsat.org>
---
 target/mips/tcg/translate.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 519b00121f6..47db35d7dd9 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -13616,7 +13616,6 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 TCGv t0;
 TCGv t1;
 TCGv v1_t;
-TCGv v2_t;
 int16_t imm;
 
 if ((ret == 0) && (check_ret == 1)) {
@@ -13627,10 +13626,8 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 t0 = tcg_temp_new();
 t1 = tcg_temp_new();
 v1_t = tcg_temp_new();
-v2_t = tcg_temp_new();
 
 gen_load_gpr(v1_t, v1);
-gen_load_gpr(v2_t, v2);
 
 switch (op1) {
 case OPC_EXTR_W_DSP:
@@ -13830,7 +13827,6 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 tcg_temp_free(t0);
 tcg_temp_free(t1);
 tcg_temp_free(v1_t);
-tcg_temp_free(v2_t);
 }
 
 /* End MIPSDSP functions. */
-- 
2.31.1




[PULL 09/17] target/mips: Use tcg_constant_i32() in gen_msa_3rf()

2021-10-17 Thread Philippe Mathieu-Daudé
Avoid using a TCG temporary by moving Data Format to the constant pool.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-6-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index bbe9146513a..e107cad57ee 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -1790,10 +1790,22 @@ static void gen_msa_3rf(DisasContext *ctx)
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tws = tcg_const_i32(ws);
 TCGv_i32 twt = tcg_const_i32(wt);
-TCGv_i32 tdf = tcg_temp_new_i32();
+TCGv_i32 tdf;
 
 /* adjust df value for floating-point instruction */
-tcg_gen_movi_i32(tdf, df + 2);
+switch (MASK_MSA_3RF(ctx->opcode)) {
+case OPC_MUL_Q_df:
+case OPC_MADD_Q_df:
+case OPC_MSUB_Q_df:
+case OPC_MULR_Q_df:
+case OPC_MADDR_Q_df:
+case OPC_MSUBR_Q_df:
+tdf = tcg_constant_i32(df + 1);
+break;
+default:
+tdf = tcg_constant_i32(df + 2);
+break;
+}
 
 switch (MASK_MSA_3RF(ctx->opcode)) {
 case OPC_FCAF_df:
@@ -1836,7 +1848,6 @@ static void gen_msa_3rf(DisasContext *ctx)
 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MUL_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FCULT_df:
@@ -1846,14 +1857,12 @@ static void gen_msa_3rf(DisasContext *ctx)
 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MADD_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FCLE_df:
 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MSUB_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FCULE_df:
@@ -1896,7 +1905,6 @@ static void gen_msa_3rf(DisasContext *ctx)
 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MULR_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FSULT_df:
@@ -1906,7 +1914,6 @@ static void gen_msa_3rf(DisasContext *ctx)
 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MADDR_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FSLE_df:
@@ -1916,7 +1923,6 @@ static void gen_msa_3rf(DisasContext *ctx)
 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_MSUBR_Q_df:
-tcg_gen_movi_i32(tdf, df + 1);
 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
 break;
 case OPC_FSULE_df:
@@ -1934,7 +1940,6 @@ static void gen_msa_3rf(DisasContext *ctx)
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
 tcg_temp_free_i32(twt);
-tcg_temp_free_i32(tdf);
 }
 
 static void gen_msa_2r(DisasContext *ctx)
-- 
2.31.1




[PULL 17/17] via-ide: Avoid using isa_get_irq()

2021-10-17 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

Use via_isa_set_irq() which better encapsulates irq handling in the
vt82xx model and avoids using isa_get_irq() that has a comment saying
it should not be used.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: 
<26cb1848c9fc0360df7a57c2c9ba5e03c4a692b5.1634259980.git.bala...@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/via.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index e91dad632a9..82def819c41 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -29,7 +29,7 @@
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
 #include "trace.h"
 
@@ -112,7 +112,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }
 
-qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
 }
 
 static void via_ide_reset(DeviceState *dev)
-- 
2.31.1




[PULL 15/17] vt82c686: Move common code to via_isa_realize

2021-10-17 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

The vt82c686b_realize and vt8231_realize methods are almost identical,
factor out the common parts to a via_isa_realize function to avoid
code duplication.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: 
<7cb7a16ff4daf8f48d576246255bea1fd355207c.1634259980.git.bala...@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 67 ---
 1 file changed, 29 insertions(+), 38 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index f57f3e70679..5b41539f2cd 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -542,6 +542,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA)
 struct ViaISAState {
 PCIDevice dev;
 qemu_irq cpu_intr;
+ISABus *isa_bus;
 ViaSuperIOState *via_sio;
 };
 
@@ -572,6 +573,29 @@ static void via_isa_request_i8259_irq(void *opaque, int 
irq, int level)
 qemu_set_irq(s->cpu_intr, level);
 }
 
+static void via_isa_realize(PCIDevice *d, Error **errp)
+{
+ViaISAState *s = VIA_ISA(d);
+DeviceState *dev = DEVICE(d);
+qemu_irq *isa_irq;
+int i;
+
+qdev_init_gpio_out(dev, &s->cpu_intr, 1);
+isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
+s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
+  &error_fatal);
+isa_bus_irqs(s->isa_bus, i8259_init(s->isa_bus, *isa_irq));
+i8254_pit_init(s->isa_bus, 0x40, 0, NULL);
+i8257_dma_init(s->isa_bus, 0);
+mc146818_rtc_init(s->isa_bus, 2000, NULL);
+
+for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
+if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
+d->wmask[i] = 0;
+}
+}
+}
+
 /* TYPE_VT82C686B_ISA */
 
 static void vt82c686b_write_config(PCIDevice *d, uint32_t addr,
@@ -610,27 +634,10 @@ static void vt82c686b_isa_reset(DeviceState *dev)
 static void vt82c686b_realize(PCIDevice *d, Error **errp)
 {
 ViaISAState *s = VIA_ISA(d);
-DeviceState *dev = DEVICE(d);
-ISABus *isa_bus;
-qemu_irq *isa_irq;
-int i;
 
-qdev_init_gpio_out(dev, &s->cpu_intr, 1);
-isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
-isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
-  &error_fatal);
-isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
-i8254_pit_init(isa_bus, 0x40, 0, NULL);
-i8257_dma_init(isa_bus, 0);
-s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus,
+via_isa_realize(d, errp);
+s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus,
TYPE_VT82C686B_SUPERIO));
-mc146818_rtc_init(isa_bus, 2000, NULL);
-
-for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
-if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
-d->wmask[i] = 0;
-}
-}
 }
 
 static void vt82c686b_class_init(ObjectClass *klass, void *data)
@@ -691,26 +698,10 @@ static void vt8231_isa_reset(DeviceState *dev)
 static void vt8231_realize(PCIDevice *d, Error **errp)
 {
 ViaISAState *s = VIA_ISA(d);
-DeviceState *dev = DEVICE(d);
-ISABus *isa_bus;
-qemu_irq *isa_irq;
-int i;
 
-qdev_init_gpio_out(dev, &s->cpu_intr, 1);
-isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
-isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
-  &error_fatal);
-isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
-i8254_pit_init(isa_bus, 0x40, 0, NULL);
-i8257_dma_init(isa_bus, 0);
-s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus, TYPE_VT8231_SUPERIO));
-mc146818_rtc_init(isa_bus, 2000, NULL);
-
-for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
-if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
-d->wmask[i] = 0;
-}
-}
+via_isa_realize(d, errp);
+s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus,
+   TYPE_VT8231_SUPERIO));
 }
 
 static void vt8231_class_init(ObjectClass *klass, void *data)
-- 
2.31.1




[PULL 12/17] target/mips: Fix DEXTRV_S.H DSP opcode

2021-10-17 Thread Philippe Mathieu-Daudé
While for the DEXTR_S.H opcode:

  "The shift argument is provided in the instruction."

For the DEXTRV_S.H opcode we have:

  "The five least-significant bits of register rs provide the
   shift argument, interpreted as a five-bit unsigned integer;
   the remaining bits in rs are ignored."

While 't1' contains the 'rs' register content (the shift value
for DEXTR_S.H), we need to load the value of 'rs' for DEXTRV_S.H.
We can directly use the v1_t TCG register which already contains
this shift value.

Fixes: b53371ed5d4 ("target-mips: Add ASE DSP accumulator instructions")
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211013215652.1764551-1-f4...@amsat.org>
---
 target/mips/tcg/translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 5fdeb67e82b..519b00121f6 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -13796,8 +13796,7 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 break;
 case OPC_DEXTRV_S_H:
 tcg_gen_movi_tl(t0, v2);
-tcg_gen_movi_tl(t1, v1);
-gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
+gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
 break;
 case OPC_DEXTRV_L:
 tcg_gen_movi_tl(t0, v2);
-- 
2.31.1




[PULL 08/17] target/mips: Use tcg_constant_i32() in gen_msa_2r()

2021-10-17 Thread Philippe Mathieu-Daudé
Avoid using a TCG temporary by moving Data Format to the constant pool.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211003175743.3738710-5-f4...@amsat.org>
---
 target/mips/tcg/msa_translate.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index 5e8f80f2f23..bbe9146513a 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -1946,7 +1946,6 @@ static void gen_msa_2r(DisasContext *ctx)
 uint8_t df = (ctx->opcode >> 16) & 0x3;
 TCGv_i32 twd = tcg_const_i32(wd);
 TCGv_i32 tws = tcg_const_i32(ws);
-TCGv_i32 tdf = tcg_const_i32(df);
 
 switch (MASK_MSA_2R(ctx->opcode)) {
 case OPC_FILL_df:
@@ -1957,7 +1956,8 @@ static void gen_msa_2r(DisasContext *ctx)
 break;
 }
 #endif
-gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
+gen_helper_msa_fill_df(cpu_env, tcg_constant_i32(df),
+   twd, tws); /* trs */
 break;
 case OPC_NLOC_df:
 switch (df) {
@@ -2015,7 +2015,6 @@ static void gen_msa_2r(DisasContext *ctx)
 
 tcg_temp_free_i32(twd);
 tcg_temp_free_i32(tws);
-tcg_temp_free_i32(tdf);
 }
 
 static void gen_msa_2rf(DisasContext *ctx)
-- 
2.31.1




Re: [PATCH v8 01/78] target/riscv: fix TB_FLAGS bits overlapping bug for rvv/rvh

2021-10-17 Thread Alistair Francis
On Fri, Oct 15, 2021 at 5:50 PM  wrote:
>
> From: Frank Chang 
>
> TB_FLAGS mem_idx bits was extended from 2 bits to 3 bits in
> commit: c445593, but other TB_FLAGS bits for rvv and rvh were
> not shift as well so these bits may overlap with each other when
> rvv is enabled.
>
> Signed-off-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h   | 14 +++---
>  target/riscv/translate.c |  2 +-
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d70f63ddfe6..d63a08b6e4c 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -380,7 +380,6 @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState 
> *env,
>  target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
>  void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
>
> -#define TB_FLAGS_MMU_MASK   7
>  #define TB_FLAGS_PRIV_MMU_MASK3
>  #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
>  #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
> @@ -389,13 +388,14 @@ typedef CPURISCVState CPUArchState;
>  typedef RISCVCPU ArchCPU;
>  #include "exec/cpu-all.h"
>
> -FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
> -FIELD(TB_FLAGS, LMUL, 3, 2)
> -FIELD(TB_FLAGS, SEW, 5, 3)
> -FIELD(TB_FLAGS, VILL, 8, 1)
> +FIELD(TB_FLAGS, MEM_IDX, 0, 3)
> +FIELD(TB_FLAGS, VL_EQ_VLMAX, 3, 1)
> +FIELD(TB_FLAGS, LMUL, 4, 2)
> +FIELD(TB_FLAGS, SEW, 6, 3)
> +FIELD(TB_FLAGS, VILL, 9, 1)
>  /* Is a Hypervisor instruction load/store allowed? */
> -FIELD(TB_FLAGS, HLSX, 9, 1)
> -FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
> +FIELD(TB_FLAGS, HLSX, 10, 1)
> +FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
>
>  bool riscv_cpu_is_32bit(CPURISCVState *env);
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index f23bc919c08..a7a66cf9db1 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -544,7 +544,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  uint32_t tb_flags = ctx->base.tb->flags;
>
>  ctx->pc_succ_insn = ctx->base.pc_first;
> -ctx->mem_idx = tb_flags & TB_FLAGS_MMU_MASK;
> +ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>  ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>  ctx->priv_ver = env->priv_ver;
>  #if !defined(CONFIG_USER_ONLY)
> --
> 2.25.1
>
>



[PULL 14/17] via-ide: Set user_creatable to false

2021-10-17 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

This model only works as a function of the via superio chip not as a
standalone PCI device.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211015092159.3e863748...@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/via.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 94cc2142c70..e91dad632a9 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -217,6 +217,9 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
 
 dc->reset = via_ide_reset;
 dc->vmsd = &vmstate_ide_pci;
+/* Reason: only works as function of VIA southbridge */
+dc->user_creatable = false;
+
 k->realize = via_ide_realize;
 k->exit = via_ide_exitfn;
 k->vendor_id = PCI_VENDOR_ID_VIA;
-- 
2.31.1




[PULL 16/17] vt82c686: Add a method to VIA_ISA to raise ISA interrupts

2021-10-17 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

Other functions in the VT82xx chips need to raise ISA interrupts. Keep
a reference to them in the device state and add via_isa_set_irq() to
allow setting their state.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Jiaxun Yang 
Message-Id: 
<778c04dc2c8affac060b8edf9e8d7dab3c3e04eb.1634259980.git.bala...@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/isa/vt82c686.h |  4 
 hw/isa/vt82c686.c | 10 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 0f01aaa4710..56ac141be38 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -1,6 +1,8 @@
 #ifndef HW_VT82C686_H
 #define HW_VT82C686_H
 
+#include "hw/pci/pci.h"
+
 #define TYPE_VT82C686B_ISA "vt82c686b-isa"
 #define TYPE_VT82C686B_PM "vt82c686b-pm"
 #define TYPE_VT8231_ISA "vt8231-isa"
@@ -8,4 +10,6 @@
 #define TYPE_VIA_AC97 "via-ac97"
 #define TYPE_VIA_MC97 "via-mc97"
 
+void via_isa_set_irq(PCIDevice *d, int n, int level);
+
 #endif
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 5b41539f2cd..8f656251b8d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -542,6 +542,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA)
 struct ViaISAState {
 PCIDevice dev;
 qemu_irq cpu_intr;
+qemu_irq *isa_irqs;
 ISABus *isa_bus;
 ViaSuperIOState *via_sio;
 };
@@ -567,6 +568,12 @@ static const TypeInfo via_isa_info = {
 },
 };
 
+void via_isa_set_irq(PCIDevice *d, int n, int level)
+{
+ViaISAState *s = VIA_ISA(d);
+qemu_set_irq(s->isa_irqs[n], level);
+}
+
 static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
 {
 ViaISAState *s = opaque;
@@ -584,7 +591,8 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
 s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
   &error_fatal);
-isa_bus_irqs(s->isa_bus, i8259_init(s->isa_bus, *isa_irq));
+s->isa_irqs = i8259_init(s->isa_bus, *isa_irq);
+isa_bus_irqs(s->isa_bus, s->isa_irqs);
 i8254_pit_init(s->isa_bus, 0x40, 0, NULL);
 i8257_dma_init(s->isa_bus, 0);
 mc146818_rtc_init(s->isa_bus, 2000, NULL);
-- 
2.31.1




Re: [PATCH v3] hw/riscv: virt: Use machine->ram as the system memory

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 1:09 PM MingWang Li  wrote:
>
> From: Mingwang Li 
>
> If default main_mem is used to be registered as the system memory,
> other memory cannot be initialized. Therefore, the system memory
> should be initialized to the machine->ram, which consists of the
> default main_mem and other possible memory required by applications,
> such as shared hugepage memory in DPDK.
>
> Also, the mc->defaul_ram_id should be set to the default main_mem,
> such as "riscv_virt_board.ram" for the virt machine.
>
> Signed-off-by: Mingwang Li 
> Signed-off-by: Yifei Jiang 
> Reviewed-by: Alistair Francis 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  hw/riscv/virt.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index ec0cb69b8c..b3b431c847 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -771,7 +771,6 @@ static void virt_machine_init(MachineState *machine)
>  const MemMapEntry *memmap = virt_memmap;
>  RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
>  MemoryRegion *system_memory = get_system_memory();
> -MemoryRegion *main_mem = g_new(MemoryRegion, 1);
>  MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
>  char *plic_hart_config, *soc_name;
>  target_ulong start_addr = memmap[VIRT_DRAM].base;
> @@ -890,10 +889,8 @@ static void virt_machine_init(MachineState *machine)
>  }
>
>  /* register system main memory (actual RAM) */
> -memory_region_init_ram(main_mem, NULL, "riscv_virt_board.ram",
> -   machine->ram_size, &error_fatal);
>  memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
> -main_mem);
> +machine->ram);
>
>  /* create device tree */
>  create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> @@ -1032,6 +1029,7 @@ static void virt_machine_class_init(ObjectClass *oc, 
> void *data)
>  mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
>  mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
>  mc->numa_mem_supported = true;
> +mc->default_ram_id = "riscv_virt_board.ram";
>
>  machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
>
> --
> 2.19.1
>
>



Re: [PATCH v3 2/6] target/riscv: zfh: half-precision computational

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:08 PM  wrote:
>
> From: Kito Cheng 
>
> Signed-off-by: Kito Cheng 
> Signed-off-by: Chih-Min Chao 
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/fpu_helper.c |  86 +++
>  target/riscv/helper.h |  13 +++
>  target/riscv/insn32.decode|  11 ++
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 129 ++
>  target/riscv/internals.h  |  16 +++
>  5 files changed, 255 insertions(+)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index d62f4709002..20bb89ad14f 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -81,6 +81,15 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
> rm)
>  set_float_rounding_mode(softrm, &env->fp_status);
>  }
>
> +static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
> +   uint64_t rs3, int flags)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +float16 frs3 = check_nanbox_h(rs3);
> +return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, 
> &env->fp_status));
> +}
> +
>  static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
> uint64_t rs3, int flags)
>  {
> @@ -102,6 +111,12 @@ uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t 
> frs1, uint64_t frs2,
>  return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
>  }
>
> +uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
> +uint64_t frs3)
> +{
> +return do_fmadd_h(env, frs1, frs2, frs3, 0);
> +}
> +
>  uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
>  uint64_t frs3)
>  {
> @@ -115,6 +130,12 @@ uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t 
> frs1, uint64_t frs2,
>&env->fp_status);
>  }
>
> +uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
> +uint64_t frs3)
> +{
> +return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
> +}
> +
>  uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
>   uint64_t frs3)
>  {
> @@ -128,6 +149,12 @@ uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t 
> frs1, uint64_t frs2,
>&env->fp_status);
>  }
>
> +uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
> + uint64_t frs3)
> +{
> +return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
> +}
> +
>  uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
>   uint64_t frs3)
>  {
> @@ -142,6 +169,13 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t 
> frs1, uint64_t frs2,
>float_muladd_negate_product, &env->fp_status);
>  }
>
> +uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
> + uint64_t frs3)
> +{
> +return do_fmadd_h(env, frs1, frs2, frs3,
> +  float_muladd_negate_c | float_muladd_negate_product);
> +}
> +
>  uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
>  {
>  float32 frs1 = check_nanbox_s(rs1);
> @@ -374,3 +408,55 @@ target_ulong helper_fclass_d(uint64_t frs1)
>  {
>  return fclass_d(frs1);
>  }
> +
> +uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return nanbox_h(float16_add(frs1, frs2, &env->fp_status));
> +}
> +
> +uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return nanbox_h(float16_sub(frs1, frs2, &env->fp_status));
> +}
> +
> +uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return nanbox_h(float16_mul(frs1, frs2, &env->fp_status));
> +}
> +
> +uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return nanbox_h(float16_div(frs1, frs2, &env->fp_status));
> +}
> +
> +uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ?
> +float16_minnum(frs1, frs2, &env->fp_status) :
> +float16_minimum_number(frs1, frs2, &env->fp_status));
> +}
> +
> +uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check

Re: [PATCH v3 3/6] target/riscv: zfh: half-precision convert and move

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:09 PM  wrote:
>
> From: Kito Cheng 
>
> Signed-off-by: Kito Cheng 
> Signed-off-by: Chih-Min Chao 
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 
> ---
>  target/riscv/fpu_helper.c |  67 +
>  target/riscv/helper.h |  12 +
>  target/riscv/insn32.decode|  19 ++
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 288 ++
>  target/riscv/translate.c  |  10 +
>  5 files changed, 396 insertions(+)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 20bb89ad14f..2ed9b03193c 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -460,3 +460,70 @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
>  float16 frs1 = check_nanbox_h(rs1);
>  return nanbox_h(float16_sqrt(frs1, &env->fp_status));
>  }
> +
> +target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return float16_to_int32(frs1, &env->fp_status);
> +}
> +
> +target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return (int32_t)float16_to_uint32(frs1, &env->fp_status);
> +}
> +
> +target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return float16_to_int64(frs1, &env->fp_status);
> +}
> +
> +target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return float16_to_uint64(frs1, &env->fp_status);
> +}
> +
> +uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
> +{
> +return nanbox_h(int32_to_float16((int32_t)rs1, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
> +{
> +return nanbox_h(uint32_to_float16((uint32_t)rs1, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1)
> +{
> +return nanbox_h(int64_to_float16(rs1, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1)
> +{
> +return nanbox_h(uint64_to_float16(rs1, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
> +{
> +float32 frs1 = check_nanbox_s(rs1);
> +return nanbox_h(float32_to_float16(frs1, true, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return nanbox_s(float16_to_float32(frs1, true, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
> +{
> +return nanbox_h(float64_to_float16(rs1, true, &env->fp_status));
> +}
> +
> +uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return float16_to_float64(frs1, true, &env->fp_status);
> +}
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index c6c0323fafc..b50672d1684 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -74,6 +74,18 @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, 
> i64)
>  DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
>  DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
>  DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_h_d, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_w_h, TCG_CALL_NO_RWG, tl, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_wu_h, TCG_CALL_NO_RWG, tl, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_l_h, TCG_CALL_NO_RWG, tl, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_lu_h, TCG_CALL_NO_RWG, tl, env, i64)
> +DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl)
> +DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
> +DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
> +DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
>
>  /* Special functions */
>  DEF_HELPER_2(csrr, tl, env, int)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 66c231a3010..ba40f3e7f89 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -739,5 +739,24 @@ fsub_h 110  . . ... . 1010011 @r_rm
>  fmul_h 0001010  . . ... . 1010011 @r_rm
>  fdiv_h 0001110  . . ... . 1010011 @r_rm
>  fsqrt_h0101110  0 . ... . 1010011 @r2_rm
> +fsgnj_h0010010  . . 000 . 1010011 @r
> +fsgnjn_h   0010010  . . 001 . 1010011 @r
> +fsgnjx_h   0010010  . . 010 . 1010011 @r
>  fmin_h 0010110  . . 000 . 1010011 @r
>  fmax_h 0010110  . . 001 . 1010011 @r
> +fcvt_h_s   0100010  0 . ... . 1010011 @r2_rm
> +fcvt_s_h   0

Re: [PATCH v3 4/6] target/riscv: zfh: half-precision floating-point compare

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:12 PM  wrote:
>
> From: Kito Cheng 
>
> Signed-off-by: Kito Cheng 
> Signed-off-by: Chih-Min Chao 
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/fpu_helper.c | 21 +
>  target/riscv/helper.h |  3 ++
>  target/riscv/insn32.decode|  3 ++
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 37 +++
>  4 files changed, 64 insertions(+)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 2ed9b03193c..ec2009ee65b 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -461,6 +461,27 @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
>  return nanbox_h(float16_sqrt(frs1, &env->fp_status));
>  }
>
> +target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return float16_le(frs1, frs2, &env->fp_status);
> +}
> +
> +target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return float16_lt(frs1, frs2, &env->fp_status);
> +}
> +
> +target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +float16 frs2 = check_nanbox_h(rs2);
> +return float16_eq_quiet(frs1, frs2, &env->fp_status);
> +}
> +
>  target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
>  {
>  float16 frs1 = check_nanbox_h(rs1);
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index b50672d1684..9c89521d4ad 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -74,6 +74,9 @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, 
> i64)
>  DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
>  DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
>  DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
> +DEF_HELPER_FLAGS_3(fle_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
> +DEF_HELPER_FLAGS_3(flt_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
> +DEF_HELPER_FLAGS_3(feq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
>  DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
>  DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
>  DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index ba40f3e7f89..3906c9fb201 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -751,6 +751,9 @@ fcvt_d_h   011  00010 . ... . 1010011 @r2_rm
>  fcvt_w_h   1100010  0 . ... . 1010011 @r2_rm
>  fcvt_wu_h  1100010  1 . ... . 1010011 @r2_rm
>  fmv_x_h1110010  0 . 000 . 1010011 @r2
> +feq_h  1010010  . . 010 . 1010011 @r
> +flt_h  1010010  . . 001 . 1010011 @r
> +fle_h  1010010  . . 000 . 1010011 @r
>  fcvt_h_w   1101010  0 . ... . 1010011 @r2_rm
>  fcvt_h_wu  1101010  1 . ... . 1010011 @r2_rm
>  fmv_h_x010  0 . 000 . 1010011 @r2
> diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
> b/target/riscv/insn_trans/trans_rvzfh.c.inc
> index d1250257666..8d0959a6671 100644
> --- a/target/riscv/insn_trans/trans_rvzfh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> @@ -335,6 +335,43 @@ static bool trans_fcvt_h_d(DisasContext *ctx, 
> arg_fcvt_h_d *a)
>  return true;
>  }
>
> +static bool trans_feq_h(DisasContext *ctx, arg_feq_h *a)
> +{
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +TCGv dest = dest_gpr(ctx, a->rd);
> +
> +gen_helper_feq_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> +gen_set_gpr(ctx, a->rd, dest);
> +return true;
> +}
> +
> +static bool trans_flt_h(DisasContext *ctx, arg_flt_h *a)
> +{
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +TCGv dest = dest_gpr(ctx, a->rd);
> +
> +gen_helper_flt_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> +gen_set_gpr(ctx, a->rd, dest);
> +
> +return true;
> +}
> +
> +static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a)
> +{
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +TCGv dest = dest_gpr(ctx, a->rd);
> +
> +gen_helper_fle_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> +gen_set_gpr(ctx, a->rd, dest);
> +return true;
> +}
> +
>  static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a)
>  {
>  REQUIRE_FPU;
> --
> 2.25.1
>
>



Re: [PATCH v3 5/6] target/riscv: zfh: half-precision floating-point classify

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:11 PM  wrote:
>
> From: Kito Cheng 
>
> Signed-off-by: Kito Cheng 
> Signed-off-by: Chih-Min Chao 
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/fpu_helper.c |  6 ++
>  target/riscv/helper.h |  1 +
>  target/riscv/insn32.decode|  1 +
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 12 
>  4 files changed, 20 insertions(+)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index ec2009ee65b..388e23ca670 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -482,6 +482,12 @@ target_ulong helper_feq_h(CPURISCVState *env, uint64_t 
> rs1, uint64_t rs2)
>  return float16_eq_quiet(frs1, frs2, &env->fp_status);
>  }
>
> +target_ulong helper_fclass_h(uint64_t rs1)
> +{
> +float16 frs1 = check_nanbox_h(rs1);
> +return fclass_h(frs1);
> +}
> +
>  target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
>  {
>  float16 frs1 = check_nanbox_h(rs1);
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 9c89521d4ad..d25cf725c57 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -89,6 +89,7 @@ DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl)
>  DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
>  DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
>  DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
> +DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
>
>  /* Special functions */
>  DEF_HELPER_2(csrr, tl, env, int)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 3906c9fb201..6c4cde216bc 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -754,6 +754,7 @@ fmv_x_h1110010  0 . 000 . 1010011 @r2
>  feq_h  1010010  . . 010 . 1010011 @r
>  flt_h  1010010  . . 001 . 1010011 @r
>  fle_h  1010010  . . 000 . 1010011 @r
> +fclass_h   1110010  0 . 001 . 1010011 @r2
>  fcvt_h_w   1101010  0 . ... . 1010011 @r2_rm
>  fcvt_h_wu  1101010  1 . ... . 1010011 @r2_rm
>  fmv_h_x010  0 . 000 . 1010011 @r2
> diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
> b/target/riscv/insn_trans/trans_rvzfh.c.inc
> index 8d0959a6671..0549e25fb45 100644
> --- a/target/riscv/insn_trans/trans_rvzfh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> @@ -372,6 +372,18 @@ static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a)
>  return true;
>  }
>
> +static bool trans_fclass_h(DisasContext *ctx, arg_fclass_h *a)
> +{
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +TCGv dest = dest_gpr(ctx, a->rd);
> +
> +gen_helper_fclass_h(dest, cpu_fpr[a->rs1]);
> +gen_set_gpr(ctx, a->rd, dest);
> +return true;
> +}
> +
>  static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a)
>  {
>  REQUIRE_FPU;
> --
> 2.25.1
>
>



Re: [PATCH v3 1/6] target/riscv: zfh: half-precision load and store

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:08 PM  wrote:
>
> From: Kito Cheng 
>
> Signed-off-by: Kito Cheng 
> Signed-off-by: Chih-Min Chao 
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 
> ---
>  target/riscv/cpu.c|  1 +
>  target/riscv/cpu.h|  1 +
>  target/riscv/insn32.decode|  4 ++
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 65 +++
>  target/riscv/translate.c  |  8 +++
>  5 files changed, 79 insertions(+)
>  create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1d69d1887e6..8c579dc297b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -601,6 +601,7 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
>  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),

This change should be after patch 5. The idea is that we add the
functionality and then allow users to enable it.

Otherwise:

Reviewed-by: Alistair Francis 

Alistair

>  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
>  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
>  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 9e55b2f5b17..88684e72be1 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -297,6 +297,7 @@ struct RISCVCPU {
>  bool ext_counters;
>  bool ext_ifencei;
>  bool ext_icsr;
> +bool ext_zfh;
>
>  char *priv_spec;
>  char *user_spec;
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 2f251dac1bb..b36a3d8dbf8 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -726,3 +726,7 @@ binv   0110100 .. 001 . 0110011 @r
>  binvi  01101. ... 001 . 0010011 @sh
>  bset   0010100 .. 001 . 0110011 @r
>  bseti  00101. ... 001 . 0010011 @sh
> +
> +# *** RV32 Zfh Extension ***
> +flh   . 001 . 111 @i
> +fsh...  . . 001 . 0100111 @s
> diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
> b/target/riscv/insn_trans/trans_rvzfh.c.inc
> new file mode 100644
> index 000..dad1d703d72
> --- /dev/null
> +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> @@ -0,0 +1,65 @@
> +/*
> + * RISC-V translation routines for the RV64Zfh Standard Extension.
> + *
> + * Copyright (c) 2020 Chih-Min Chao, chihmin.c...@sifive.com
> + *
> + * 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 .
> + */
> +
> +#define REQUIRE_ZFH(ctx) do { \
> +if (!ctx->ext_zfh) {  \
> +return false; \
> +} \
> +} while (0)
> +
> +static bool trans_flh(DisasContext *ctx, arg_flh *a)
> +{
> +TCGv_i64 dest;
> +TCGv t0;
> +
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> +if (a->imm) {
> +TCGv temp = temp_new(ctx);
> +tcg_gen_addi_tl(temp, t0, a->imm);
> +t0 = temp;
> +}
> +
> +dest = cpu_fpr[a->rd];
> +tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TEUW);
> +gen_nanbox_h(dest, dest);
> +
> +mark_fs_dirty(ctx);
> +return true;
> +}
> +
> +static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
> +{
> +TCGv t0;
> +
> +REQUIRE_FPU;
> +REQUIRE_ZFH(ctx);
> +
> +t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> +if (a->imm) {
> +TCGv temp = tcg_temp_new();
> +tcg_gen_addi_tl(temp, t0, a->imm);
> +t0 = temp;
> +}
> +
> +tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW);
> +
> +return true;
> +}
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index d2442f0cf5d..75048149f5a 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -69,6 +69,7 @@ typedef struct DisasContext {
>  bool w;
>  bool virt_enabled;
>  bool ext_ifencei;
> +bool ext_zfh;
>  bool hlsx;
>  /* vector extension */
>  bool vill;
> @@ -118,6 +119,11 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>  tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
> 

Re: [PATCH v3 6/6] target/riscv: zfh: implement zfhmin extension

2021-10-17 Thread Alistair Francis
On Sat, Oct 16, 2021 at 7:13 PM  wrote:
>
> From: Frank Chang 
>
> Zfhmin extension is a subset of Zfh extension, consisting only of data
> transfer and conversion instructions.
>
> If enabled, only the following instructions from Zfh extension are
> included:
>   * flh, fsh, fmv.x.h, fmv.h.x, fcvt.s.h, fcvt.h.s
>   * If D extension is present: fcvt.d.h, fcvt.h.d
>
> Signed-off-by: Frank Chang 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c|  1 +
>  target/riscv/cpu.h|  1 +
>  target/riscv/insn_trans/trans_rvzfh.c.inc | 22 ++
>  target/riscv/translate.c  |  2 ++
>  4 files changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8c579dc297b..4c0e6532164 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -602,6 +602,7 @@ static Property riscv_cpu_properties[] = {
>  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),
> +DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
>  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
>  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
>  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 88684e72be1..d70f63ddfe6 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -298,6 +298,7 @@ struct RISCVCPU {
>  bool ext_ifencei;
>  bool ext_icsr;
>  bool ext_zfh;
> +bool ext_zfhmin;
>
>  char *priv_spec;
>  char *user_spec;
> diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
> b/target/riscv/insn_trans/trans_rvzfh.c.inc
> index 0549e25fb45..5a7cac89585 100644
> --- a/target/riscv/insn_trans/trans_rvzfh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> @@ -22,13 +22,19 @@
>  } \
>  } while (0)
>
> +#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do {   \
> +if (!(ctx->ext_zfh || ctx->ext_zfhmin)) { \
> +return false; \
> +} \
> +} while (0)
> +
>  static bool trans_flh(DisasContext *ctx, arg_flh *a)
>  {
>  TCGv_i64 dest;
>  TCGv t0;
>
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  t0 = get_gpr(ctx, a->rs1, EXT_NONE);
>  if (a->imm) {
> @@ -50,7 +56,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
>  TCGv t0;
>
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  t0 = get_gpr(ctx, a->rs1, EXT_NONE);
>  if (a->imm) {
> @@ -283,7 +289,7 @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
>  static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  gen_set_rm(ctx, a->rm);
>  gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
> @@ -296,7 +302,7 @@ static bool trans_fcvt_s_h(DisasContext *ctx, 
> arg_fcvt_s_h *a)
>  static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>  REQUIRE_EXT(ctx, RVD);
>
>  gen_set_rm(ctx, a->rm);
> @@ -311,7 +317,7 @@ static bool trans_fcvt_d_h(DisasContext *ctx, 
> arg_fcvt_d_h *a)
>  static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  gen_set_rm(ctx, a->rm);
>  gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
> @@ -324,7 +330,7 @@ static bool trans_fcvt_h_s(DisasContext *ctx, 
> arg_fcvt_h_s *a)
>  static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>  REQUIRE_EXT(ctx, RVD);
>
>  gen_set_rm(ctx, a->rm);
> @@ -441,7 +447,7 @@ static bool trans_fcvt_h_wu(DisasContext *ctx, 
> arg_fcvt_h_wu *a)
>  static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  TCGv dest = dest_gpr(ctx, a->rd);
>
> @@ -461,7 +467,7 @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h 
> *a)
>  static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
>  {
>  REQUIRE_FPU;
> -REQUIRE_ZFH(ctx);
> +REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
>  TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 442ef42f441..f23bc919c08 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -70,6 +70,7 @@ typedef struct DisasContext {
>  bool virt_enabled;
>  bool ext_ifencei;
>  bool ext_zfh;
> +bool ext_zfhmin;
>  bool

Re: [PATCH v3 2/2] target/riscv: change the api for single/double fmin/fmax

2021-10-17 Thread Alistair Francis
On Sun, Oct 17, 2021 at 4:59 PM Frank Chang  wrote:
>
> On Sun, Oct 17, 2021 at 8:55 AM Frank Chang  wrote:
>>
>> On Sun, Oct 17, 2021 at 1:56 AM Richard Henderson 
>>  wrote:
>>>
>>> On 10/16/21 1:52 AM, Frank Chang wrote:
>>> > On Sat, Oct 16, 2021 at 1:05 AM Richard Henderson 
>>> > >> > > wrote:
>>> >
>>> > On 10/14/21 11:54 PM, frank.ch...@sifive.com 
>>> >  wrote:
>>> >  > From: Chih-Min Chao>> > >
>>> >  >
>>> >  > The sNaN propagation behavior has been changed since
>>> >  > cd20cee7 inhttps://github.com/riscv/riscv-isa-manual
>>> > 
>>> >  >
>>> >  > Signed-off-by: Chih-Min Chao>> > >
>>> >  > ---
>>> >  >   target/riscv/fpu_helper.c | 8 
>>> >  >   1 file changed, 4 insertions(+), 4 deletions(-)
>>> >  >
>>> >  > diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
>>> >  > index 8700516a14c..1472ead2528 100644
>>> >  > --- a/target/riscv/fpu_helper.c
>>> >  > +++ b/target/riscv/fpu_helper.c
>>> >  > @@ -174,14 +174,14 @@ uint64_t helper_fmin_s(CPURISCVState *env, 
>>> > uint64_t rs1,
>>> > uint64_t rs2)
>>> >  >   {
>>> >  >   float32 frs1 = check_nanbox_s(rs1);
>>> >  >   float32 frs2 = check_nanbox_s(rs2);
>>> >  > -return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
>>> >  > +return nanbox_s(float32_minnum_noprop(frs1, frs2, 
>>> > &env->fp_status));
>>> >  >   }
>>> >
>>> > Don't you need to conditionalize behaviour on the isa revision?
>>> >
>>> >
>>> > I will pick the right API based on CPU privilege spec version.
>>>
>>> There's a separate F-extension revision number: 2.2.
>>>
>>> But I'll leave it up to those more knowledgeable about the revision 
>>> combinations actually
>>> present in the field to decide.
>>>
>>
>> I did some history searches on RISC-V ISA spec Github repo.
>>
>> F-extension was bumped to v2.2 at (2018/08/28):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/draft-20180828-eb78171
>> The privilege spec is v1.10-draft at the time.
>>
>> and later ratified at (2019/03/26):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/IMFDQC-Ratification-20190305
>>
>> The spec was updated to use IEEE 754-2019 min/max functions in commit: 
>> #cd20cee7 (2019/06/05).
>
>
> Sorry, the commit date is 2017/06/05, not 2019/06/05.
>
> But I think it's probably easier and clearer to just introduce an extra 
> fext_ver variable.
> We can set CPUs which are Privilege spec v1.10 to RVF v2.0 
> (FEXT_VERSION_2_00_0),
> and others with Privilege spec v1.11 to RVF v2.2 (FEXT_VERSION_2_02_0).

I think it's probably simpler to just tie this to the priv_spec. It's
not completely accurate, but it should be close enough. Otherwise we
have the risk of having too many version variables and it becomes a
pain for users to deal with.

If the unpriv spec is better, we could also introduce that. We will
probably need that one day for something else anyway.

If you feel that we really need a fext_ver (to avoid large software
breakage for example) then it's also ok, we just need to justify why.

Alistair

>
> Any comments are welcome.
>
> Regards,
> Frank Chang
>
>>
>>
>> Privilege spec v1.11 is ratified at (2019/06/10):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/Ratified-IMFDQC-and-Priv-v1.11
>>
>> In fact, Unprivileged spec v2.2 was released at (2017/05/10):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-user-2.2
>>
>> and Privilege spec v1.10 was released at (2017/05/10):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-priv-1.10
>>
>> Privilege spec was then bumped to v1.11-draft in the next draft release 
>> right after v1.10 (2018/05/24):
>> https://github.com/riscv/riscv-isa-manual/releases/tag/draft-20180524001518-9981ad7
>> (RVF was still v2.0 at the time.)
>>
>> It seems that when Privilege spec v1.11 was ratified, RVF had been bumped to 
>> v2.2,
>> and when Privilege spec v1.10 was ratified, RVF was still v2.0.
>>
>> As in QEMU, there's only priv_ver variable existing for now.
>> So unless we introduce other variables like: unpriv_ver or fext_ver.
>> Otherwise, I think using priv_ver is still valid here.
>> Though it is not accurate, somehow confused,
>> and may not be true anymore in future standards.
>>
>> Let me know which way is better for our maintenance.
>>
>> Thanks,
>> Frank Chang
>>
>>> r~



Re: [PATCH 1/2] hw/misc/bcm2835_property: Fix framebuffer with recent RPi kernels

2021-10-17 Thread Benjamin Herrenschmidt
On Sun, 2021-10-17 at 17:08 +0200, Philippe Mathieu-Daudé wrote:
> Hi Benjamin,
> 
> On 10/17/21 09:48, Benjamin Herrenschmidt wrote:
> > The framebuffer driver fails to initialize with recent Raspberry Pi
> > kernels, such as the ones shipped in the current RaspiOS images
> > (with the out of tree bcm2708_fb.c driver)
> 
> Which particular version?

The one I dug out of 2021-05-07-raspios-buster-arm64-lite.img (note
that this then fails to boot some time after the fb is setup, even
after the fix, in the vchip driver init (before serial is up even).

That said, the same fb problem happens with 5.10.60-v8+ from raspbian.

I'm not sure your fix will work on these, see below:

> +case 0x00040013: /* Get number of displays */
> +stl_le_phys(&s->dma_as, value + 12, 0 /* old fw: unique display 
> */);
> +resplen = 4;
> +break;
> 
This should have been equivalen to not having the property. However,
the failure path in the driver looks like this (note the mismatch
between the comment and the code.. this is rpi 5.10.73 from the rpi
repo :

ret = rpi_firmware_property(fw,
RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS,
&num_displays, sizeof(u32));

/* If we fail to get the number of displays, or it returns 0, then
 * assume old firmware that doesn't have the mailbox call, so just
 * set one display
 */
if (ret || num_displays == 0) {
dev_err(&dev->dev,
"Unable to determine number of FBs. Disabling 
driver.\n");
return -ENOENT;
} else {
fbdev->firmware_supports_multifb = 1;
}

So it appears that the intention at some stage was to set only one display but
the code as written will fail to initialize the drive if the properly is absent
*or* if it returns 0.

I've just checked the rpi-5.15.y branch and it's the same.

Cheers,
Ben.





[PATCH v4 01/15] target/ppc: add MMCR0 PMCC bits to hflags

2021-10-17 Thread Daniel Henrique Barboza
We're going to add PMU support for TCG PPC64 chips, based on IBM POWER8+
emulation and following PowerISA v3.1. This requires several PMU related
registers to be exposed to userspace (problem state). PowerISA v3.1
dictates that the PMCC bits of the MMCR0 register controls the level of
access of the PMU registers to problem state.

This patch start things off by exposing both PMCC bits to hflags,
allowing us to access them via DisasContext in the read/write callbacks
that we're going to add next.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h | 6 ++
 target/ppc/helper_regs.c | 6 ++
 target/ppc/translate.c   | 4 
 3 files changed, 16 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index baa4e7c34d..0df1a5a970 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -342,6 +342,10 @@ typedef struct ppc_v3_pate_t {
 #define MSR_RI   1  /* Recoverable interrupt1*/
 #define MSR_LE   0  /* Little-endian mode   1 hflags */
 
+/* PMU bits */
+#define MMCR0_PMCC0  PPC_BIT(44) /* PMC Control bit 0 */
+#define MMCR0_PMCC1  PPC_BIT(45) /* PMC Control bit 1 */
+
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
 #define LPCR_VPM1 PPC_BIT(1)
@@ -607,6 +611,8 @@ enum {
 HFLAGS_SE = 10,  /* MSR_SE -- from elsewhere on embedded ppc */
 HFLAGS_FP = 13,  /* MSR_FP */
 HFLAGS_PR = 14,  /* MSR_PR */
+HFLAGS_PMCC0 = 15,  /* MMCR0 PMCC bit 0 */
+HFLAGS_PMCC1 = 16,  /* MMCR0 PMCC bit 1 */
 HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
 HFLAGS_VR = 25,  /* MSR_VR if cpu has VRE */
 
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 1bfb480ecf..99562edd57 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -109,6 +109,12 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 if (env->spr[SPR_LPCR] & LPCR_HR) {
 hflags |= 1 << HFLAGS_HR;
 }
+if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
+hflags |= 1 << HFLAGS_PMCC0;
+}
+if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
+hflags |= 1 << HFLAGS_PMCC1;
+}
 
 #ifndef CONFIG_USER_ONLY
 if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 9ca78ee156..70ae4bda92 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -176,6 +176,8 @@ struct DisasContext {
 bool tm_enabled;
 bool gtse;
 bool hr;
+bool mmcr0_pmcc0;
+bool mmcr0_pmcc1;
 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
 int singlestep_enabled;
 uint32_t flags;
@@ -8559,6 +8561,8 @@ static void ppc_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->tm_enabled = (hflags >> HFLAGS_TM) & 1;
 ctx->gtse = (hflags >> HFLAGS_GTSE) & 1;
 ctx->hr = (hflags >> HFLAGS_HR) & 1;
+ctx->mmcr0_pmcc0 = (hflags >> HFLAGS_PMCC0) & 1;
+ctx->mmcr0_pmcc1 = (hflags >> HFLAGS_PMCC1) & 1;
 
 ctx->singlestep_enabled = 0;
 if ((hflags >> HFLAGS_SE) & 1) {
-- 
2.31.1




[PATCH v4 04/15] target/ppc: adding user read/write functions for PMCs

2021-10-17 Thread Daniel Henrique Barboza
Problem state needs to be able to read and write the PMU counters,
otherwise it won't be aware of any sampling result that the PMU produces
after a Perf run.

This patch does that in a similar fashion as already done in the
previous patches. PMCs 5 and 6 have a special condition, aside from the
constraints that are common with PMCs 1-4, where they are not part of the
PMU if MMCR0_PMCC is 0b11.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu_init.c| 12 +++---
 target/ppc/power8-pmu-regs.c.inc | 70 
 target/ppc/spr_tcg.h |  4 ++
 3 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index ad88e54950..65545ba9ca 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6879,27 +6879,27 @@ static void register_book3s_pmu_user_sprs(CPUPPCState 
*env)
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC56_ureg, &spr_write_PMC56_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC56_ureg, &spr_write_PMC56_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_USIAR, "USIAR",
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index fb95175183..7391851238 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -169,6 +169,56 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int 
gprn)
 
 tcg_temp_free(masked_gprn);
 }
+
+void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+if (!spr_groupA_read_allowed(ctx)) {
+return;
+}
+
+spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+/*
+ * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance
+ * Monitor, and a read attempt results in a Facility Unavailable
+ * Interrupt.
+ */
+if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) {
+gen_hvpriv_exception(ctx, POWERPC_EXCP_FU);
+return;
+}
+
+/* The remaining steps are similar to PMCs 1-4 userspace read */
+spr_read_PMC14_ureg(ctx, gprn, sprn);
+}
+
+void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+if (!spr_groupA_write_allowed(ctx)) {
+return;
+}
+
+spr_write_ureg(ctx, sprn, gprn);
+}
+
+void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+/*
+ * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance
+ * Monitor, and a write attempt results in a Facility Unavailable
+ * Interrupt.
+ */
+if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) {
+gen_hvpriv_exception(ctx, POWERPC_EXCP_FU);
+return;
+}
+
+/* The remaining steps are similar to PMCs 1-4 userspace write */
+spr_write_PMC14_ureg(ctx, sprn, gprn);
+}
 #else
 void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
 {
@@ -189,4 +239,24 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int 
gprn)
 {
 spr_noaccess(ctx, gprn, sprn);
 }
+
+void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+spr_noaccess(ctx, gprn, sprn);
+}
+
+void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+spr_noaccess(ctx, gprn, sprn);
+}
 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index cb7f40eedf..520f1ef233 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h

[PATCH v4 00/15] PPC64/TCG: Implement 'rfebb' instruction

2021-10-17 Thread Daniel Henrique Barboza
This new version presents drastic design changes across all areas, most
of them based on the feedback received in v3.

- TCG reviewers: for people looking to review only TCG related changes,
here's a summmary of where are the TCG code in the series:

* Patches that have a lot of TCG/translation changes: 1-4, 9, 13
* Patches that have TCG/translation bits: 6, 7, 10, 11

- changes in v3:

The most drastic change is in the PMU. We're now working with an
abstraction called PMUEvent that holds all the event information that
the helper functions need to process it: the PMC, the event type and an
overflow timer for cycle events. The PMU will always have 6 PMCEvent
structs, one for each counter. Counters that aren't being used in that
moment will have event type 'invalid'. These events are populated only
when MMCR1 is written. Calculating the PMC values does not require
multiple calls to 'get_PMC_event()', which has been deleted. In fact,
this design change cut 60 lines of the power8-pmu.c file compared to the
previous version, resulting in a more concise logic that will allow for
easier extension of the PMU in the future.

Another change was related to PMCC bits and access control of problem
state to PMU registers. We're now exposing both PMCC bits and doing a
proper access control for groupA regs.

A new file was created to host the PMU translation code. The 300+ lines
of the new power8-pmu-regs.c.inc file would be dumped into translate.c.

I've also changed the patch order. The exclusive EBB patches were pushed to
the end of the series. I find it easier to add the placeholders for the
PMC interrupt right at the start but populate them later on, after all
the PMU logic has already been in place, instead of adding PMU code,
then EBB, then go back to PMU code again.

All other changes were result of these decisions described above.

- patch 13 (former 08):
  * renamed arg_RFEBB to arg_XL_s
  * added Matheus' R-b
- other patches:
  * The changes were so substancial that the patch breakdown with the diffs
turned out cumbersome and contraproductive.
- v3 link: https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg01250.html 


Daniel Henrique Barboza (13):
  target/ppc: add MMCR0 PMCC bits to hflags
  target/ppc: add user read/write functions for MMCR2
  target/ppc: adding user read/write functions for PMCs
  target/ppc: introduce PMU events
  target/ppc: initialize PMUEvents on MMCR1 write
  target/ppc: PMU basic cycle count for pseries TCG
  target/ppc: enable PMU counter overflow with cycle events
  target/ppc: enable PMU instruction count
  target/ppc/power8-pmu.c: add PM_RUN_INST_CMPL (0xFA) event
  target/ppc: PMU: handle setting of PMCs while running
  target/ppc/power8-pmu.c: handle overflow bits when PMU is running
  PPC64/TCG: Implement 'rfebb' instruction
  target/ppc/excp_helper.c: EBB handling adjustments

Gustavo Romero (2):
  target/ppc: add user read/write functions for MMCR0
  target/ppc: PMU Event-Based exception support

 hw/ppc/spapr_cpu_core.c|   6 +
 target/ppc/cpu.h   |  89 +-
 target/ppc/cpu_init.c  |  38 +--
 target/ppc/excp_helper.c   |  92 ++
 target/ppc/helper.h|   5 +
 target/ppc/helper_regs.c   |  10 +
 target/ppc/insn32.decode   |   5 +
 target/ppc/meson.build |   1 +
 target/ppc/power8-pmu-regs.c.inc   | 320 +++
 target/ppc/power8-pmu.c| 410 +
 target/ppc/power8-pmu.h|  25 ++
 target/ppc/spr_tcg.h   |  12 +
 target/ppc/translate.c |  67 
 target/ppc/translate/branch-impl.c.inc |  33 ++
 14 files changed, 1093 insertions(+), 20 deletions(-)
 create mode 100644 target/ppc/power8-pmu-regs.c.inc
 create mode 100644 target/ppc/power8-pmu.c
 create mode 100644 target/ppc/power8-pmu.h
 create mode 100644 target/ppc/translate/branch-impl.c.inc

-- 
2.31.1




[PATCH v4 03/15] target/ppc: add user read/write functions for MMCR2

2021-10-17 Thread Daniel Henrique Barboza
Similar to the previous patch, let's add problem state read/write access to
the MMCR2 SPR, which is also a group A PMU SPR that needs to be filtered
to be read/written by userspace.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  9 +++
 target/ppc/cpu_init.c|  2 +-
 target/ppc/power8-pmu-regs.c.inc | 98 
 target/ppc/spr_tcg.h |  2 +
 4 files changed, 99 insertions(+), 12 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 7f80c0bb19..33e3a91f6f 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -352,6 +352,15 @@ typedef struct ppc_v3_pate_t {
 #define MMCR0_PMCC1  PPC_BIT(45) /* PMC Control bit 1 */
 /* MMCR0 userspace r/w mask */
 #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
+/* MMCR2 userspace r/w mask */
+#define MMCR2_FC1P0  PPC_BIT(1)  /* MMCR2 FCnP0 for PMC1 */
+#define MMCR2_FC2P0  PPC_BIT(10) /* MMCR2 FCnP0 for PMC2 */
+#define MMCR2_FC3P0  PPC_BIT(19) /* MMCR2 FCnP0 for PMC3 */
+#define MMCR2_FC4P0  PPC_BIT(28) /* MMCR2 FCnP0 for PMC4 */
+#define MMCR2_FC5P0  PPC_BIT(37) /* MMCR2 FCnP0 for PMC5 */
+#define MMCR2_FC6P0  PPC_BIT(46) /* MMCR2 FCnP0 for PMC6 */
+#define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
+ MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
 
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 375bdca1e1..ad88e54950 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6975,7 +6975,7 @@ static void register_power8_pmu_sup_sprs(CPUPPCState *env)
 static void register_power8_pmu_user_sprs(CPUPPCState *env)
 {
 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_MMCR2_ureg, &spr_write_MMCR2_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_USIER, "USIER",
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index 37c812dd4d..fb95175183 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -55,6 +55,33 @@ static bool spr_groupA_write_allowed(DisasContext *ctx)
 return false;
 }
 
+/*
+ * Helper function to avoid code repetition between MMCR0 and
+ * MMCR2 problem state write functions.
+ *
+ * 'ret' must be tcg_temp_freed() by the caller.
+ */
+static TCGv masked_gprn_for_spr_write(int gprn, int sprn,
+  uint64_t spr_mask)
+{
+TCGv ret = tcg_temp_new();
+TCGv t0 = tcg_temp_new();
+
+/* 'ret' starts with all mask bits cleared */
+gen_load_spr(ret, sprn);
+tcg_gen_andi_tl(ret, ret, ~(spr_mask));
+
+/* Apply the mask into 'gprn' in a temp var */
+tcg_gen_andi_tl(t0, cpu_gpr[gprn], spr_mask);
+
+/* Add the masked gprn bits into 'ret' */
+tcg_gen_or_tl(ret, ret, t0);
+
+tcg_temp_free(t0);
+
+return ret;
+}
+
 void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
 {
 TCGv t0;
@@ -79,29 +106,68 @@ void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int 
sprn)
 
 void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn)
 {
-TCGv t0, t1;
+TCGv masked_gprn;
 
 if (!spr_groupA_write_allowed(ctx)) {
 return;
 }
 
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-
 /*
  * Filter out all bits but FC, PMAO, and PMAE, according
  * to ISA v3.1, in 10.4.4 Monitor Mode Control Register 0,
  * fourth paragraph.
  */
-tcg_gen_andi_tl(t0, cpu_gpr[gprn], MMCR0_UREG_MASK);
-gen_load_spr(t1, SPR_POWER_MMCR0);
-tcg_gen_andi_tl(t1, t1, ~(MMCR0_UREG_MASK));
-/* Keep all other bits intact */
-tcg_gen_or_tl(t1, t1, t0);
-gen_store_spr(SPR_POWER_MMCR0, t1);
+masked_gprn = masked_gprn_for_spr_write(gprn, SPR_POWER_MMCR0,
+MMCR0_UREG_MASK);
+gen_store_spr(SPR_POWER_MMCR0, masked_gprn);
+
+tcg_temp_free(masked_gprn);
+}
+
+void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+TCGv t0;
+
+if (!spr_groupA_read_allowed(ctx)) {
+return;
+}
+
+t0 = tcg_temp_new();
+
+/*
+ * On read, filter out all bits that are not FCnP0 bits.
+ * When MMCR0[PMCC] is set to 0b10 or 0b11, providing
+ * problem state programs read/write access to MMCR2,
+ * only the FCnP0 bits can be accessed. All other bits are
+ * not changed when mtspr is executed in problem state, and
+ * all other bits return 0s when mfspr is executed in problem
+ * state, according to ISA v3.1, section 10.4.6 Monitor Mode
+ * Control Register 2, p. 1316, third paragraph.
+ */
+gen_load_spr(t0, SPR_POWER_MMCR2);
+tcg_gen_andi_tl(t0, t0, MMCR2_UREG_MASK);
+tcg_gen_mov_tl(cpu_gpr[gprn], t0);
 
 tcg_temp_free(t0);
-tcg_temp_free(t1);
+}
+
+void spr_

[PATCH v4 06/15] target/ppc: initialize PMUEvents on MMCR1 write

2021-10-17 Thread Daniel Henrique Barboza
The value of MMCR1 determines the events that are going to be sampled by
the programmable counters (PMCs 1-4). PMCs 5 and 6 are always counting
instructions and cycles respectively and aren't affected by MMCR1.

This patch adds a helper to initialize PMCs 1-4 PMUEvents when writing
the MMCR1 register. The following events are considered valid at this
moment:

- For PMCs 1-4, event 0x2 is the implementation dependent value of
PMU_EVENT_INSTRUCTIONS and event 0x1E is the implementation dependent
value of PMU_EVENT_CYCLES. These events are supported by IBM Power chips
since Power8, at least, and the Linux Perf driver makes use of these
events until kernel v5.15;

- for PMC1, event 0xF0 is the architected PowerISA event for cycles.
Event 0xFE is the architected PowerISA event for instructions.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h | 11 ++
 target/ppc/cpu_init.c|  2 +-
 target/ppc/helper.h  |  1 +
 target/ppc/power8-pmu-regs.c.inc | 16 +
 target/ppc/power8-pmu.c  | 59 
 target/ppc/spr_tcg.h |  1 +
 6 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 21591ec725..aaf503c8ff 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -382,6 +382,17 @@ typedef struct PMUEvent {
 #define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
  MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
 
+#define MMCR1_EVT_SIZE 8
+/* extract64() does a right shift before extracting */
+#define MMCR1_PMC1SEL_START 32
+#define MMCR1_PMC1EVT_EXTR (64 - MMCR1_PMC1SEL_START - MMCR1_EVT_SIZE)
+#define MMCR1_PMC2SEL_START 40
+#define MMCR1_PMC2EVT_EXTR (64 - MMCR1_PMC2SEL_START - MMCR1_EVT_SIZE)
+#define MMCR1_PMC3SEL_START 48
+#define MMCR1_PMC3EVT_EXTR (64 - MMCR1_PMC3SEL_START - MMCR1_EVT_SIZE)
+#define MMCR1_PMC4SEL_START 56
+#define MMCR1_PMC4EVT_EXTR (64 - MMCR1_PMC4SEL_START - MMCR1_EVT_SIZE)
+
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
 #define LPCR_VPM1 PPC_BIT(1)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 65545ba9ca..7c9ed5dfe1 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6824,7 +6824,7 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
  KVM_REG_PPC_MMCR0, 0x);
 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_MMCR1,
  KVM_REG_PPC_MMCR1, 0x);
 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
  SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fc5bae8330 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -20,6 +20,7 @@ DEF_HELPER_1(rfscv, void, env)
 DEF_HELPER_1(hrfid, void, env)
 DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
+DEF_HELPER_2(store_mmcr1, void, env, tl)
 #endif
 DEF_HELPER_1(check_tlb_flush_local, void, env)
 DEF_HELPER_1(check_tlb_flush_global, void, env)
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index 7391851238..a0a64e76ad 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -219,6 +219,17 @@ void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int 
gprn)
 /* The remaining steps are similar to PMCs 1-4 userspace write */
 spr_write_PMC14_ureg(ctx, sprn, gprn);
 }
+
+void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn)
+{
+gen_helper_store_mmcr1(cpu_env, cpu_gpr[gprn]);
+
+/*
+ * Writes in MMCR1 must force a new translation block, allowing
+ * the PMU to calculate events with more accuracy.
+ */
+ctx->base.is_jmp = DISAS_EXIT_UPDATE;
+}
 #else
 void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
 {
@@ -259,4 +270,9 @@ void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int 
gprn)
 {
 spr_noaccess(ctx, gprn, sprn);
 }
+
+void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn)
+{
+spr_write_generic(ctx, sprn, gprn);
+}
 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 42452b5870..9a0b544b04 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -23,6 +23,65 @@
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 
+/*
+ * For PMCs 1-4, IBM POWER chips has support for an implementation
+ * dependent event, 0x1E, that enables cycle counting. The Linux kernel
+ * makes extensive use of 0x1E, so let's also support it.
+ *
+ * Likewise, event 0x2 is an implementation-dependent event that IBM
+ * POWER chips implement (at least since POWER8) that is equivalent to
+ * PM_INST_CMPL. Let's support this event on PMCs 1-4 as well.
+ */
+static void define_enabled_events(CP

[PATCH v4 02/15] target/ppc: add user read/write functions for MMCR0

2021-10-17 Thread Daniel Henrique Barboza
From: Gustavo Romero 

Userspace need access to PMU SPRs to be able to operate the PMU. One of
such SPRs is MMCR0.

MMCR0, as defined by PowerISA v3.1, is classified as a 'group A' PMU
register. This class of registers has common read/write rules that are
governed by MMCR0 PMCC bits. MMCR0 is also not fully exposed to problem
state: only MMCR0_FC, MMCR0_PMAO and MMCR0_PMAE bits are
readable/writable in this case.

This patch exposes MMCR0 to userspace by doing the following:

- two new callbacks, spr_read_MMCR0_ureg() and spr_write_MMCR0_ureg(),
are added to be used as problem state read/write callbacks of UMMCR0.
Both callbacks filters the amount of bits userspace is able to
read/write by using a MMCR0_UREG_MASK;

- problem state access control is done by the spr_groupA_read_allowed()
and spr_groupA_write_allowed() helpers. These helpers will read the
current PMCC bits from DisasContext and check whether the read/write
MMCR0 operation is valid or noti;

- to avoid putting exclusive PMU logic into the already loaded
translate.c file, let's create a new 'power8-pmu-regs.c.inc' file that
will hold all the spr_read/spr_write functions of PMU registers.

The 'power8' name of this new file intends to hint about the proven
support of the PMU logic to be added. The code has been tested with the
IBM POWER chip family, POWER8 being the oldest version tested. This
doesn't mean that the PMU logic will break with any other PPC64 chip
that implements Book3s, but rather that we can't assert that it works
properly with any Book3s compliant chip.

CC: Gustavo Romero 
Signed-off-by: Gustavo Romero 
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |   7 ++
 target/ppc/cpu_init.c|   2 +-
 target/ppc/power8-pmu-regs.c.inc | 116 +++
 target/ppc/spr_tcg.h |   2 +
 target/ppc/translate.c   |   2 +
 5 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 target/ppc/power8-pmu-regs.c.inc

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 0df1a5a970..7f80c0bb19 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -343,8 +343,15 @@ typedef struct ppc_v3_pate_t {
 #define MSR_LE   0  /* Little-endian mode   1 hflags */
 
 /* PMU bits */
+#define MMCR0_FC PPC_BIT(32) /* Freeze Counters  */
+#define MMCR0_PMAO   PPC_BIT(56) /* Perf Monitor Alert Ocurred */
+#define MMCR0_PMAE   PPC_BIT(37) /* Perf Monitor Alert Enable */
+#define MMCR0_EBEPPC_BIT(43) /* Perf Monitor EBB Enable */
+#define MMCR0_FCECE  PPC_BIT(38) /* FC on Enabled Cond or Event */
 #define MMCR0_PMCC0  PPC_BIT(44) /* PMC Control bit 0 */
 #define MMCR0_PMCC1  PPC_BIT(45) /* PMC Control bit 1 */
+/* MMCR0 userspace r/w mask */
+#define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
 
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6aad01d1d3..375bdca1e1 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6867,7 +6867,7 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
 static void register_book3s_pmu_user_sprs(CPUPPCState *env)
 {
 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_MMCR0_ureg, &spr_write_MMCR0_ureg,
  &spr_read_ureg, &spr_write_ureg,
  0x);
 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
new file mode 100644
index 00..37c812dd4d
--- /dev/null
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -0,0 +1,116 @@
+/*
+ * PMU register read/write functions for TCG IBM POWER chips
+ *
+ * Copyright IBM Corp. 2021
+ *
+ * Authors:
+ *  Daniel Henrique Barboza  
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+
+/*
+ * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the
+ * PMCs) has problem state read access.
+ *
+ * Read acccess is granted for all PMCC values but 0b01, where a
+ * Facility Unavailable Interrupt will occur.
+ */
+static bool spr_groupA_read_allowed(DisasContext *ctx)
+{
+if (!ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) {
+gen_hvpriv_exception(ctx, POWERPC_EXCP_FU);
+return false;
+}
+
+return true;
+}
+
+/*
+ * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the
+ * PMCs) has problem state write access.
+ *
+ * Write acccess is granted for PMCC values 0b10 and 0b11. Userspace
+ * writing with PMCC 0b00 will generate a Hypervisor Emulation
+ * Assistance Interrupt. Userspace writing with PMCC 0b01 will
+ * generate a Facility Unavailable Interrupt.
+ */
+static bool spr_groupA_write_allowed(DisasContext *ctx)
+{
+if (ctx->mmcr0_pmcc0) {
+return true;
+ 

[PATCH v4 07/15] target/ppc: PMU basic cycle count for pseries TCG

2021-10-17 Thread Daniel Henrique Barboza
This patch adds the barebones of the PMU logic by enabling cycle
counting. The overall logic goes as follows:

- a helper is added to control the PMU state on each MMCR0 write. This
allows for the PMU to start/stop as the frozen counter bit (MMCR0_FC)
is cleared or set;

- MMCR0 reg initial value is set to 0x8000 (MMCR0_FC set) to avoid
having to spin the PMU right at system init;

- the intended usage is to freeze the counters by setting MMCR0_FC, do
any additional setting of events to be counted via MMCR1 and enable
the PMU by zeroing MMCR0_FC. Software must freeze counters to read the
results - on the fly reading of the PMCs will return the starting value
of each one. This act of unfreezing the PMU, counting cycles and then
freezing the PMU again is being called a cycle count session.

Our base CPU frequency is fixed at 1Ghz for both powernv and pseries
clock, so this assumption is also carried on here to determine that 1
nanosecond equals 1 CPU cycle. Cycle value is then calculated by
subtracting the current time the PMU was frozen against the time in
which the PMU started spining.

The counter specific frozen bits MMCR0_FC14 and MMCR0_FC56 were also
added as a mean to further control which PMCs were supposed to be
counting cycles during the session.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  9 
 target/ppc/cpu_init.c|  6 +--
 target/ppc/helper.h  |  1 +
 target/ppc/power8-pmu-regs.c.inc | 23 -
 target/ppc/power8-pmu.c  | 83 
 target/ppc/spr_tcg.h |  1 +
 6 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index aaf503c8ff..e6bb55cb1a 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -370,6 +370,9 @@ typedef struct PMUEvent {
 #define MMCR0_FCECE  PPC_BIT(38) /* FC on Enabled Cond or Event */
 #define MMCR0_PMCC0  PPC_BIT(44) /* PMC Control bit 0 */
 #define MMCR0_PMCC1  PPC_BIT(45) /* PMC Control bit 1 */
+#define MMCR0_PMCC   PPC_BITMASK(44, 45) /* PMC Control */
+#define MMCR0_FC14   PPC_BIT(58) /* PMC Freeze Counters 1-4 bit */
+#define MMCR0_FC56   PPC_BIT(59) /* PMC Freeze Counters 5-6 bit */
 /* MMCR0 userspace r/w mask */
 #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
 /* MMCR2 userspace r/w mask */
@@ -1223,6 +1226,12 @@ struct CPUPPCState {
 uint64_t tm_tar;
 
 PMUEvent pmu_events[PMU_EVENTS_NUM];
+
+/*
+ * PMU base time value used by the PMU to calculate
+ * running cycles.
+ */
+uint64_t pmu_base_time;
 };
 
 #define SET_FIT_PERIOD(a_, b_, c_, d_)  \
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 7c9ed5dfe1..ffcd08a947 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6820,8 +6820,8 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
 {
 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCR0, 0x);
+ &spr_read_generic, &spr_write_MMCR0,
+ KVM_REG_PPC_MMCR0, 0x8000);
 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
  SPR_NOACCESS, SPR_NOACCESS,
  &spr_read_generic, &spr_write_MMCR1,
@@ -6869,7 +6869,7 @@ static void register_book3s_pmu_user_sprs(CPUPPCState 
*env)
 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
  &spr_read_MMCR0_ureg, &spr_write_MMCR0_ureg,
  &spr_read_ureg, &spr_write_ureg,
- 0x);
+ 0x8000);
 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
  &spr_read_ureg, SPR_NOACCESS,
  &spr_read_ureg, &spr_write_ureg,
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fc5bae8330..ea82d08ad5 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -20,6 +20,7 @@ DEF_HELPER_1(rfscv, void, env)
 DEF_HELPER_1(hrfid, void, env)
 DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
+DEF_HELPER_2(store_mmcr0, void, env, tl)
 DEF_HELPER_2(store_mmcr1, void, env, tl)
 #endif
 DEF_HELPER_1(check_tlb_flush_local, void, env)
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index a0a64e76ad..8b3ffd9c1a 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -104,6 +104,17 @@ void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int 
sprn)
 tcg_temp_free(t0);
 }
 
+static void write_MMCR0_common(DisasContext *ctx, TCGv val)
+{
+/*
+ * helper_store_mmcr0 will make clock based operations that
+ * will cause 'bad icount read' errors if we do not execute
+ * gen_icount_io_start() beforehand.
+ */
+gen_icount_io_start(ctx);
+gen_helper_store_mmcr0(cpu_env, val);
+}
+
 void spr_write_MMCR0_ureg(DisasContex

[PATCH v4 05/15] target/ppc: introduce PMU events

2021-10-17 Thread Daniel Henrique Barboza
This patch starts an IBM Power8+ compatible PMU implementation by adding
the representation of PMU events that we are going to sample, PMUEvent.
This struct represents a Perf event, determined by the PMUEventType
enum, that is being sampled by a specific counter 'sprn'. PMUEvent also
contains an overflow timer that will be used to trigger cycle overflows
when cycle events are being sampled. This timer will call
cpu_ppc_pmu_timer_cb(), which in turn calls fire_PMC_interrupt(). Both
functions are stubs that will be implemented later on when EBB support
is added.

The PMU has 6 PMUEvents all the time, one for each counter. Events that
aren't available (i.e. the counter isn't running) will be of type
'PMU_EVENT_INVALID'. Other types added in this patch are
PMU_EVENT_CYCLES and PMU_EVENT_INSTRUCTIONS. More types will be added
later on.

Two new helper files are created to host this new logic.
cpu_ppc_pmu_init() will init all PMUEvents during CPU init time.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr_cpu_core.c |  6 
 target/ppc/cpu.h| 22 
 target/ppc/meson.build  |  1 +
 target/ppc/power8-pmu.c | 75 +
 target/ppc/power8-pmu.h | 25 ++
 5 files changed, 129 insertions(+)
 create mode 100644 target/ppc/power8-pmu.c
 create mode 100644 target/ppc/power8-pmu.h

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 58e7341cb7..45abffd891 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -20,6 +20,7 @@
 #include "target/ppc/kvm_ppc.h"
 #include "hw/ppc/ppc.h"
 #include "target/ppc/mmu-hash64.h"
+#include "target/ppc/power8-pmu.h"
 #include "sysemu/numa.h"
 #include "sysemu/reset.h"
 #include "sysemu/hw_accel.h"
@@ -266,6 +267,11 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 return false;
 }
 
+/* Init PMU interrupt timer (TCG only) */
+if (!kvm_enabled()) {
+cpu_ppc_pmu_init(env);
+}
+
 if (!sc->pre_3_0_migration) {
 vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state,
  cpu->machine_data);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 33e3a91f6f..21591ec725 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -296,6 +296,26 @@ typedef struct ppc_v3_pate_t {
 uint64_t dw1;
 } ppc_v3_pate_t;
 
+/* PMU related structs and defines */
+#define PMU_EVENTS_NUM 6
+typedef enum {
+PMU_EVENT_INVALID = 0,
+PMU_EVENT_CYCLES,
+PMU_EVENT_INSTRUCTIONS,
+} PMUEventType;
+
+typedef struct PMUEvent {
+int sprn;
+PMUEventType type;
+
+/*
+ * Timer used to fire performance monitor alerts
+ * when counting cycles.
+ */
+QEMUTimer *cyc_overflow_timer;
+
+} PMUEvent;
+
 /*/
 /* Machine state register bits definition*/
 #define MSR_SF   63 /* Sixty-four-bit modehflags */
@@ -1190,6 +1210,8 @@ struct CPUPPCState {
 uint32_t tm_vscr;
 uint64_t tm_dscr;
 uint64_t tm_tar;
+
+PMUEvent pmu_events[PMU_EVENTS_NUM];
 };
 
 #define SET_FIT_PERIOD(a_, b_, c_, d_)  \
diff --git a/target/ppc/meson.build b/target/ppc/meson.build
index b85f295703..a49a8911e0 100644
--- a/target/ppc/meson.build
+++ b/target/ppc/meson.build
@@ -51,6 +51,7 @@ ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files(
   'mmu-book3s-v3.c',
   'mmu-hash64.c',
   'mmu-radix64.c',
+  'power8-pmu.c',
 ))
 
 target_arch += {'ppc': ppc_ss}
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
new file mode 100644
index 00..42452b5870
--- /dev/null
+++ b/target/ppc/power8-pmu.c
@@ -0,0 +1,75 @@
+/*
+ * PMU emulation helpers for TCG IBM POWER chips
+ *
+ *  Copyright IBM Corp. 2021
+ *
+ * Authors:
+ *  Daniel Henrique Barboza  
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "power8-pmu.h"
+#include "cpu.h"
+#include "helper_regs.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "hw/ppc/ppc.h"
+
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+
+static void fire_PMC_interrupt(PowerPCCPU *cpu)
+{
+CPUPPCState *env = &cpu->env;
+
+if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_EBE)) {
+return;
+}
+
+/* PMC interrupt not implemented yet */
+return;
+}
+
+static void cpu_ppc_pmu_timer_cb(void *opaque)
+{
+PowerPCCPU *cpu = opaque;
+
+fire_PMC_interrupt(cpu);
+}
+
+void cpu_ppc_pmu_init(CPUPPCState *env)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+int i;
+
+/*
+ * PMC1 event first, PMC2 second and so on. PMC5 and PMC6
+ * PMUEvent are always the same regardless of MMCR1.
+ */
+for (i = 0; i < PMU_EVENTS_NUM; i++) {
+PMUEvent *event = &env-

[PATCH v4 09/15] target/ppc: enable PMU instruction count

2021-10-17 Thread Daniel Henrique Barboza
The PMU is already counting cycles by calculating time elapsed in
nanoseconds. Counting instructions is a different matter and requires
another approach.

This patch adds the capability of counting completed instructions
(Perf event PM_INST_CMPL) by counting the amount of instructions
translated in each translation block right before exiting it.

A new pmu_count_insns() helper in translation.c was added to do that.
After verifying that the PMU is running (MMCR0_FC bit not set), call
helper_insns_inc(). This new helper from power8-pmu.c will add the
instructions to the relevant counters. It'll also be responsible for
triggering counter negative overflows as it is already being done with
cycles.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  1 +
 target/ppc/helper.h  |  1 +
 target/ppc/helper_regs.c |  4 +++
 target/ppc/power8-pmu-regs.c.inc |  6 
 target/ppc/power8-pmu.c  | 41 
 target/ppc/translate.c   | 47 
 6 files changed, 100 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 074d844741..185a6166aa 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -665,6 +665,7 @@ enum {
 HFLAGS_PR = 14,  /* MSR_PR */
 HFLAGS_PMCC0 = 15,  /* MMCR0 PMCC bit 0 */
 HFLAGS_PMCC1 = 16,  /* MMCR0 PMCC bit 1 */
+HFLAGS_MMCR0FC = 17, /* MMCR0 FC bit */
 HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
 HFLAGS_VR = 25,  /* MSR_VR if cpu has VRE */
 
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index ea82d08ad5..5814e2f251 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -22,6 +22,7 @@ DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
 DEF_HELPER_2(store_mmcr0, void, env, tl)
 DEF_HELPER_2(store_mmcr1, void, env, tl)
+DEF_HELPER_2(insns_inc, void, env, i32)
 #endif
 DEF_HELPER_1(check_tlb_flush_local, void, env)
 DEF_HELPER_1(check_tlb_flush_global, void, env)
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 99562edd57..875c2fdfc6 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -115,6 +115,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
 hflags |= 1 << HFLAGS_PMCC1;
 }
+if (env->spr[SPR_POWER_MMCR0] & MMCR0_FC) {
+hflags |= 1 << HFLAGS_MMCR0FC;
+}
+
 
 #ifndef CONFIG_USER_ONLY
 if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index 8b3ffd9c1a..f8ca44cfdc 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -113,6 +113,12 @@ static void write_MMCR0_common(DisasContext *ctx, TCGv val)
  */
 gen_icount_io_start(ctx);
 gen_helper_store_mmcr0(cpu_env, val);
+
+/*
+ * End the translation block because MMCR0 writes can change
+ * ctx->pmu_frozen.
+ */
+ctx->base.is_jmp = DISAS_EXIT_UPDATE;
 }
 
 void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn)
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 724a1a4038..e9c6b9dfec 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -102,6 +102,33 @@ static bool pmu_event_has_overflow_enabled(CPUPPCState 
*env, PMUEvent *event)
 return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
 }
 
+static bool pmu_events_increment_insns(CPUPPCState *env, uint32_t num_insns)
+{
+bool overflow_triggered = false;
+int i;
+
+/* PMC6 never counts instructions. */
+for (i = 0; i < PMU_EVENTS_NUM - 1; i++) {
+PMUEvent *event = &env->pmu_events[i];
+
+if (!pmu_event_is_active(env, event) ||
+event->type != PMU_EVENT_INSTRUCTIONS) {
+continue;
+}
+
+env->spr[event->sprn] += num_insns;
+
+if (env->spr[event->sprn] >= COUNTER_NEGATIVE_VAL &&
+pmu_event_has_overflow_enabled(env, event)) {
+
+overflow_triggered = true;
+env->spr[event->sprn] = COUNTER_NEGATIVE_VAL;
+}
+}
+
+return overflow_triggered;
+}
+
 static void pmu_events_update_cycles(CPUPPCState *env)
 {
 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -248,6 +275,20 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
 return;
 }
 
+/* This helper assumes that the PMC is running. */
+void helper_insns_inc(CPUPPCState *env, uint32_t num_insns)
+{
+bool overflow_triggered;
+PowerPCCPU *cpu;
+
+overflow_triggered = pmu_events_increment_insns(env, num_insns);
+
+if (overflow_triggered) {
+cpu = env_archcpu(env);
+fire_PMC_interrupt(cpu);
+}
+}
+
 static void cpu_ppc_pmu_timer_cb(void *opaque)
 {
 PowerPCCPU *cpu = opaque;
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 96e8703dd1..acc0e50194 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -178,6 +178,7 @@ struct DisasContex

[PATCH v4 08/15] target/ppc: enable PMU counter overflow with cycle events

2021-10-17 Thread Daniel Henrique Barboza
The PowerISA v3.1 defines that if the proper bits are set (MMCR0_PMC1CE
for PMC1 and MMCR0_PMCjCE for the remaining PMCs), counter negative
conditions are enabled. This means that if the counter value overflows
(i.e. exceeds 0x8000) a performance monitor alert will occur. This alert
can trigger an event-based exception (to be implemented in the next patches)
if the MMCR0_EBE bit is set.

For now, overflowing the counter when the PMC is counting cycles will
just trigger a performance monitor alert. This is done by starting the
overflow timer of the PMUEvent to expire in the moment the overflow
would be occuring. The timer will call fire_PMC_interrupt() (via
cpu_ppc_pmu_timer_cb) which will trigger the PMU alert and, if the
conditions are met, an EBB exception.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h|  2 ++
 target/ppc/power8-pmu.c | 75 +++--
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e6bb55cb1a..074d844741 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -373,6 +373,8 @@ typedef struct PMUEvent {
 #define MMCR0_PMCC   PPC_BITMASK(44, 45) /* PMC Control */
 #define MMCR0_FC14   PPC_BIT(58) /* PMC Freeze Counters 1-4 bit */
 #define MMCR0_FC56   PPC_BIT(59) /* PMC Freeze Counters 5-6 bit */
+#define MMCR0_PMC1CE PPC_BIT(48) /* MMCR0 PMC1 Condition Enabled */
+#define MMCR0_PMCjCE PPC_BIT(49) /* MMCR0 PMCj Condition Enabled */
 /* MMCR0 userspace r/w mask */
 #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
 /* MMCR2 userspace r/w mask */
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 55906c70a2..724a1a4038 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -23,6 +23,8 @@
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 
+#define COUNTER_NEGATIVE_VAL 0x8000
+
 /*
  * For PMCs 1-4, IBM POWER chips has support for an implementation
  * dependent event, 0x1E, that enables cycle counting. The Linux kernel
@@ -91,6 +93,15 @@ static bool pmu_event_is_active(CPUPPCState *env, PMUEvent 
*event)
 return !(env->spr[SPR_POWER_MMCR0] & MMCR0_FC56);
 }
 
+static bool pmu_event_has_overflow_enabled(CPUPPCState *env, PMUEvent *event)
+{
+if (event->sprn == SPR_POWER_PMC1) {
+return env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE;
+}
+
+return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
+}
+
 static void pmu_events_update_cycles(CPUPPCState *env)
 {
 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -121,6 +132,52 @@ static void pmu_events_update_cycles(CPUPPCState *env)
 }
 }
 
+static void pmu_delete_timers(CPUPPCState *env)
+{
+int i;
+
+for (i = 0; i < PMU_EVENTS_NUM; i++) {
+PMUEvent *event = &env->pmu_events[i];
+
+if (event->sprn == SPR_POWER_PMC5) {
+continue;
+}
+
+timer_del(event->cyc_overflow_timer);
+}
+}
+
+static void pmu_events_start_overflow_timers(CPUPPCState *env)
+{
+uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+int64_t timeout;
+int i;
+
+env->pmu_base_time = now;
+
+/*
+ * Scroll through all PMCs ad start counter overflow timers for
+ * PM_CYC events, if needed.
+ */
+for (i = 0; i < PMU_EVENTS_NUM; i++) {
+PMUEvent *event = &env->pmu_events[i];
+
+if (!pmu_event_is_active(env, event) ||
+!(event->type == PMU_EVENT_CYCLES) ||
+!pmu_event_has_overflow_enabled(env, event)) {
+continue;
+}
+
+if (env->spr[event->sprn] >= COUNTER_NEGATIVE_VAL) {
+timeout =  0;
+} else {
+timeout  = COUNTER_NEGATIVE_VAL - env->spr[event->sprn];
+}
+
+timer_mod(event->cyc_overflow_timer, now + timeout);
+}
+}
+
 /*
  * A cycle count session consists of the basic operations we
  * need to do to support PM_CYC events: redefine a new base_time
@@ -128,8 +185,22 @@ static void pmu_events_update_cycles(CPUPPCState *env)
  */
 static void start_cycle_count_session(CPUPPCState *env)
 {
-/* Just define pmu_base_time for now */
-env->pmu_base_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+bool overflow_enabled = env->spr[SPR_POWER_MMCR0] &
+(MMCR0_PMC1CE | MMCR0_PMCjCE);
+
+/*
+ * Always delete existing overflow timers when starting a
+ * new cycle counting session.
+ */
+pmu_delete_timers(env);
+
+if (!overflow_enabled) {
+/* Define pmu_base_time and leave */
+env->pmu_base_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+return;
+}
+
+pmu_events_start_overflow_timers(env);
 }
 
 void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
-- 
2.31.1




[PATCH v4 10/15] target/ppc/power8-pmu.c: add PM_RUN_INST_CMPL (0xFA) event

2021-10-17 Thread Daniel Henrique Barboza
PM_RUN_INST_CMPL, instructions completed with the run latch set, is
the architected PowerISA v3.1 event defined with PMC4SEL = 0xFA.

Implement it by checking for the CTRL RUN bit before incrementing the
counter. To make this work properly we also need to force a new
translation block each time SPR_CTRL is written. A small tweak in
pmu_events_increment_insns() is then needed to only increment this event
if the thread has the run latch.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h|  4 
 target/ppc/cpu_init.c   |  2 +-
 target/ppc/power8-pmu.c | 23 ---
 target/ppc/spr_tcg.h|  1 +
 target/ppc/translate.c  | 12 
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 185a6166aa..6f9a48a5a1 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -302,6 +302,7 @@ typedef enum {
 PMU_EVENT_INVALID = 0,
 PMU_EVENT_CYCLES,
 PMU_EVENT_INSTRUCTIONS,
+PMU_EVENT_INSN_RUN_LATCH,
 } PMUEventType;
 
 typedef struct PMUEvent {
@@ -398,6 +399,9 @@ typedef struct PMUEvent {
 #define MMCR1_PMC4SEL_START 56
 #define MMCR1_PMC4EVT_EXTR (64 - MMCR1_PMC4SEL_START - MMCR1_EVT_SIZE)
 
+/* PMU uses CTRL_RUN to sample PM_RUN_INST_CMPL */
+#define CTRL_RUN PPC_BIT(63)
+
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
 #define LPCR_VPM1 PPC_BIT(1)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index ffcd08a947..eb1a0320b9 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6748,7 +6748,7 @@ static void register_book3s_ctrl_sprs(CPUPPCState *env)
 {
 spr_register(env, SPR_CTRL, "SPR_CTRL",
  SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
+ SPR_NOACCESS, &spr_write_CTRL,
  0x);
 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
  &spr_read_ureg, SPR_NOACCESS,
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index e9c6b9dfec..3946314e9c 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -62,6 +62,15 @@ static void define_enabled_events(CPUPPCState *env)
 event->type = PMU_EVENT_CYCLES;
 }
 break;
+case 0xFA:
+/*
+ * PMC4SEL = 0xFA is the "instructions completed
+ * with run latch set" event.
+ */
+if (event->sprn == SPR_POWER_PMC4) {
+event->type = PMU_EVENT_INSN_RUN_LATCH;
+}
+break;
 case 0xFE:
 /*
  * PMC1SEL = 0xFE is the architected PowerISA v3.1
@@ -110,13 +119,21 @@ static bool pmu_events_increment_insns(CPUPPCState *env, 
uint32_t num_insns)
 /* PMC6 never counts instructions. */
 for (i = 0; i < PMU_EVENTS_NUM - 1; i++) {
 PMUEvent *event = &env->pmu_events[i];
+bool insn_event = event->type == PMU_EVENT_INSTRUCTIONS ||
+  event->type == PMU_EVENT_INSN_RUN_LATCH;
 
-if (!pmu_event_is_active(env, event) ||
-event->type != PMU_EVENT_INSTRUCTIONS) {
+if (!pmu_event_is_active(env, event) || !insn_event) {
 continue;
 }
 
-env->spr[event->sprn] += num_insns;
+if (event->type == PMU_EVENT_INSTRUCTIONS) {
+env->spr[event->sprn] += num_insns;
+}
+
+if (event->type == PMU_EVENT_INSN_RUN_LATCH &&
+env->spr[SPR_CTRL] & CTRL_RUN) {
+env->spr[event->sprn] += num_insns;
+}
 
 if (env->spr[event->sprn] >= COUNTER_NEGATIVE_VAL &&
 pmu_event_has_overflow_enabled(env, event)) {
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index 82f9dc16a4..28126da6e2 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -27,6 +27,7 @@ void spr_read_generic(DisasContext *ctx, int gprn, int sprn);
 void spr_write_generic(DisasContext *ctx, int sprn, int gprn);
 void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn);
 void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn);
+void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn);
 void spr_read_xer(DisasContext *ctx, int gprn, int sprn);
 void spr_write_xer(DisasContext *ctx, int sprn, int gprn);
 void spr_read_lr(DisasContext *ctx, int gprn, int sprn);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index acc0e50194..e2839883be 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -404,6 +404,18 @@ void spr_write_generic(DisasContext *ctx, int sprn, int 
gprn)
 spr_store_dump_spr(sprn);
 }
 
+void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
+{
+spr_write_generic(ctx, sprn, gprn);
+
+/*
+ * SPR_CTRL writes must force a new translation block,
+ * allowing the PMU to calculate the run latch events with
+ * more accuracy.
+ */
+ctx->base.is_jmp = DISAS_EXIT_UPDATE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void spr_write_generic32(DisasContext *ctx, 

[PATCH v4 12/15] target/ppc/power8-pmu.c: handle overflow bits when PMU is running

2021-10-17 Thread Daniel Henrique Barboza
Up until this moment we were assuming that the counter negative
enabled bits, PMC1CE and PMCjCE, would never be changed when the
PMU is already started.

Turns out that there is no such restriction in the PowerISA v3.1,
and software can enable/disable overflow conditions of the counters
at any time.

To support this scenario, track the overflow bits state when a
write in MMCR0 is made in which the run state of the PMU (MMCR0_FC
bit) didn't change and, if some overflow bit were changed in the
middle of a cycle count session, restart it.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/power8-pmu.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 3fc09cebe4..4bd07ba865 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -277,6 +277,30 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong 
value)
 } else {
 start_cycle_count_session(env);
 }
+} else {
+/*
+ * No change in MMCR0_FC state, but if the PMU is running and
+ * a change in the counter negative overflow bits is made,
+ * we need to restart a new cycle count session to restart
+ * the appropriate overflow timers.
+ */
+if (curr_FC) {
+return;
+}
+
+bool pmc1ce_curr = curr_value & MMCR0_PMC1CE;
+bool pmc1ce_new  = value & MMCR0_PMC1CE;
+bool pmcjce_curr = curr_value & MMCR0_PMCjCE;
+bool pmcjce_new  = value & MMCR0_PMCjCE;
+
+if (pmc1ce_curr == pmc1ce_new && pmcjce_curr == pmcjce_new) {
+return;
+}
+
+/* Update the counter with the events counted so far */
+pmu_events_update_cycles(env);
+
+start_cycle_count_session(env);
 }
 }
 
-- 
2.31.1




[PATCH v4 11/15] target/ppc: PMU: handle setting of PMCs while running

2021-10-17 Thread Daniel Henrique Barboza
The initial PMU support were made under the assumption that the counters
would be set before running the PMU and read after either freezing the
PMU manually or via a performance monitor alert.

Turns out that some EBB powerpc kernel tests set the counters after
unfreezing the counters. Setting a PMC value when the PMU is running
means that, at that moment, the baseline for calculating cycle
events needs to be updated. Updating this baseline means that we need
to update all the PMCs with their actual value at that moment. Any
existing counter negative timer needs to be discarded an a new one,
with the updated values, must be set again.

This patch does that via a new 'helper_store_pmc()' that is called in
the mtspr() callbacks of PMU counters.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu_init.c| 12 ++--
 target/ppc/helper.h  |  1 +
 target/ppc/power8-pmu-regs.c.inc | 17 -
 target/ppc/power8-pmu.c  | 18 ++
 target/ppc/spr_tcg.h |  1 +
 5 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index eb1a0320b9..cf68e2c5a7 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6832,27 +6832,27 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState 
*env)
  KVM_REG_PPC_MMCRA, 0x);
 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC1, 0x);
 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC2, 0x);
 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC3, 0x);
 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC4, 0x);
 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC5, 0x);
 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
  SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_PMC,
  KVM_REG_PPC_PMC6, 0x);
 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
  SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 5814e2f251..b0ebfaff51 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -22,6 +22,7 @@ DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
 DEF_HELPER_2(store_mmcr0, void, env, tl)
 DEF_HELPER_2(store_mmcr1, void, env, tl)
+DEF_HELPER_3(store_pmc, void, env, i32, i64)
 DEF_HELPER_2(insns_inc, void, env, i32)
 #endif
 DEF_HELPER_1(check_tlb_flush_local, void, env)
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index f8ca44cfdc..8a9e1f41ef 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -212,13 +212,23 @@ void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int 
sprn)
 spr_read_PMC14_ureg(ctx, gprn, sprn);
 }
 
+void spr_write_PMC(DisasContext *ctx, int sprn, int gprn)
+{
+TCGv_i32 t_sprn = tcg_const_i32(sprn);
+
+gen_icount_io_start(ctx);
+gen_helper_store_pmc(cpu_env, t_sprn, cpu_gpr[gprn]);
+
+tcg_temp_free_i32(t_sprn);
+}
+
 void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn)
 {
 if (!spr_groupA_write_allowed(ctx)) {
 return;
 }
 
-spr_write_ureg(ctx, sprn, gprn);
+spr_write_PMC(ctx, sprn + 0x10, gprn);
 }
 
 void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
@@ -302,4 +312,9 @@ void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn)
 {
 spr_write_generic(ctx, sprn, gprn);
 }
+
+void spr_write_PMC(DisasContext *ctx, int sprn, int gprn)
+{
+spr_write_generic(ctx, sprn, gprn);
+}
 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 3946314e9c..3fc09cebe4 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -343,4 +343,22 @@ void cpu_ppc_pmu_init(CPUPPCState *env)
 }
 }
 
+void helper_store_

[PATCH v4 13/15] PPC64/TCG: Implement 'rfebb' instruction

2021-10-17 Thread Daniel Henrique Barboza
An Event-Based Branch (EBB) allows applications to change the NIA when a
event-based exception occurs. Event-based exceptions are enabled by
setting the Branch Event Status and Control Register (BESCR). If the
event-based exception is enabled when the exception occurs, an EBB
happens.

The following operations happens during an EBB:

- Global Enable (GE) bit of BESCR is set to 0;
- bits 0-61 of the Event-Based Branch Return Register (EBBRR) are set
to the the effective address of the NIA that would have executed if the EBB
didn't happen;
- Instruction fetch and execution will continue in the effective address
contained in the Event-Based Branch Handler Register (EBBHR).

The EBB Handler will process the event and then execute the Return From
Event-Based Branch (rfebb) instruction. rfebb sets BESCR_GE and then
redirects execution to the address pointed in EBBRR. This process is
described in the PowerISA v3.1, Book II, Chapter 6 [1].

This patch implements the rfebb instruction. Descriptions of all
relevant BESCR bits are also added - this patch is only using BESCR_GE,
but the next patches will use the remaining bits.

[1] https://wiki.raptorcs.com/w/images/f/f5/PowerISA_public.v3.1.pdf

Reviewed-by: Matheus Ferst 
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h   | 13 ++
 target/ppc/excp_helper.c   | 31 
 target/ppc/helper.h|  1 +
 target/ppc/insn32.decode   |  5 
 target/ppc/translate.c |  2 ++
 target/ppc/translate/branch-impl.c.inc | 33 ++
 6 files changed, 85 insertions(+)
 create mode 100644 target/ppc/translate/branch-impl.c.inc

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 6f9a48a5a1..bccf135847 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -402,6 +402,19 @@ typedef struct PMUEvent {
 /* PMU uses CTRL_RUN to sample PM_RUN_INST_CMPL */
 #define CTRL_RUN PPC_BIT(63)
 
+/* EBB/BESCR bits */
+/* Global Enable */
+#define BESCR_GE PPC_BIT(0)
+/* External Event-based Exception Enable */
+#define BESCR_EE PPC_BIT(30)
+/* Performance Monitor Event-based Exception Enable */
+#define BESCR_PME PPC_BIT(31)
+/* External Event-based Exception Occurred */
+#define BESCR_EEO PPC_BIT(62)
+/* Performance Monitor Event-based Exception Occurred */
+#define BESCR_PMEO PPC_BIT(63)
+#define BESCR_INVALID PPC_BITMASK(32, 33)
+
 /* LPCR bits */
 #define LPCR_VPM0 PPC_BIT(0)
 #define LPCR_VPM1 PPC_BIT(1)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index b7d1767920..7be334e007 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1248,6 +1248,37 @@ void helper_hrfid(CPUPPCState *env)
 }
 #endif
 
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+void helper_rfebb(CPUPPCState *env, target_ulong s)
+{
+target_ulong msr = env->msr;
+
+/*
+ * Handling of BESCR bits 32:33 according to PowerISA v3.1:
+ *
+ * "If BESCR 32:33 != 0b00 the instruction is treated as if
+ *  the instruction form were invalid."
+ */
+if (env->spr[SPR_BESCR] & BESCR_INVALID) {
+raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+}
+
+env->nip = env->spr[SPR_EBBRR];
+
+/* Switching to 32-bit ? Crop the nip */
+if (!msr_is_64bit(env, msr)) {
+env->nip = (uint32_t)env->spr[SPR_EBBRR];
+}
+
+if (s) {
+env->spr[SPR_BESCR] |= BESCR_GE;
+} else {
+env->spr[SPR_BESCR] &= ~BESCR_GE;
+}
+}
+#endif
+
 /*/
 /* Embedded PowerPC specific helpers */
 void helper_40x_rfci(CPUPPCState *env)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index b0ebfaff51..8bc38b5e4b 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -18,6 +18,7 @@ DEF_HELPER_2(pminsn, void, env, i32)
 DEF_HELPER_1(rfid, void, env)
 DEF_HELPER_1(rfscv, void, env)
 DEF_HELPER_1(hrfid, void, env)
+DEF_HELPER_2(rfebb, void, env, tl)
 DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
 DEF_HELPER_2(store_mmcr0, void, env, tl)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..deb7374ea4 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -124,3 +124,8 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
+
+### rfebb
+&XL_s   s:uint8_t
+@XL_s   ..-- s:1 .. -   &XL_s
+RFEBB   010011-- .   0010010010 -   @XL_s
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index e2839883be..cdb1171b88 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7554,6 +7554,8 @@ static int times_4(DisasContext *ctx, int x)
 
 #include "translate/spe-impl.c.inc"
 
+#

[PATCH v4 14/15] target/ppc: PMU Event-Based exception support

2021-10-17 Thread Daniel Henrique Barboza
From: Gustavo Romero 

Following up the rfebb implementation, this patch adds the EBB exception
support that are triggered by Performance Monitor alerts. This exception
occurs when an enabled PMU condition or event happens and both MMCR0_EBE
and BESCR_PME are set.

The supported PM alerts will consist of counter negative conditions of
the PMU counters. This will be achieved by a timer mechanism that will
predict when a counter becomes negative. The PMU timer callback will set
the appropriate bits in MMCR0 and fire a PMC interrupt. The EBB
exception code will then set the appropriate BESCR bits, set the next
instruction pointer to the address pointed by the return register
(SPR_EBBRR), and redirect execution to the handler (pointed by
SPR_EBBHR).

This patch sets the basic structure of interrupts and timers. The
following patches will add the counter negative logic for the registers.

CC: Gustavo Romero 
Signed-off-by: Gustavo Romero 
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  5 -
 target/ppc/excp_helper.c | 28 
 target/ppc/power8-pmu.c  | 26 --
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index bccf135847..98b6d6bfb5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -129,8 +129,10 @@ enum {
 /* ISA 3.00 additions */
 POWERPC_EXCP_HVIRT= 101,
 POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception 
*/
+POWERPC_EXCP_EBB = 103, /* Event-based branch exception  */
+
 /* EOL   */
-POWERPC_EXCP_NB   = 103,
+POWERPC_EXCP_NB   = 104,
 /* QEMU exceptions: special cases we want to stop translation*/
 POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only  */
 };
@@ -2461,6 +2463,7 @@ enum {
 PPC_INTERRUPT_HMI,/* Hypervisor Maintenance interrupt*/
 PPC_INTERRUPT_HDOORBELL,  /* Hypervisor Doorbell interrupt*/
 PPC_INTERRUPT_HVIRT,  /* Hypervisor virtualization interrupt  */
+PPC_INTERRUPT_PMC,/* Hypervisor virtualization interrupt  */
 };
 
 /* Processor Compatibility mask (PCR) */
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 7be334e007..88aa0a84f8 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -797,6 +797,22 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 cpu_abort(cs, "Non maskable external exception "
   "is not implemented yet !\n");
 break;
+case POWERPC_EXCP_EBB:   /* Event-based branch exception */
+if ((env->spr[SPR_BESCR] & BESCR_GE) &&
+(env->spr[SPR_BESCR] & BESCR_PME)) {
+target_ulong nip;
+
+env->spr[SPR_BESCR] &= ~BESCR_GE;   /* Clear GE */
+env->spr[SPR_BESCR] |= BESCR_PMEO;  /* Set PMEO */
+env->spr[SPR_EBBRR] = env->nip; /* Save NIP for rfebb insn */
+nip = env->spr[SPR_EBBHR];  /* EBB handler */
+powerpc_set_excp_state(cpu, nip, env->msr);
+}
+/*
+ * This interrupt is handled by userspace. No need
+ * to proceed.
+ */
+return;
 default:
 excp_invalid:
 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
@@ -1044,6 +1060,18 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM);
 return;
 }
+/* PMC -> Event-based branch exception */
+if (env->pending_interrupts & (1 << PPC_INTERRUPT_PMC)) {
+/*
+ * Performance Monitor event-based exception can only
+ * occur in problem state.
+ */
+if (msr_pr == 1) {
+env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PMC);
+powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EBB);
+return;
+}
+}
 }
 
 if (env->resume_as_sreset) {
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 4bd07ba865..7ccdd03902 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -312,8 +312,30 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
 return;
 }
 
-/* PMC interrupt not implemented yet */
-return;
+if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCECE) {
+env->spr[SPR_POWER_MMCR0] &= ~MMCR0_FCECE;
+env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
+
+/* Changing MMCR0_FC demands a new hflags compute */
+hreg_compute_hflags(env);
+
+/*
+ * Delete all pending timers if we need to freeze
+ * the PMC. We'll restart them when the PMC starts
+ * running again.
+ */
+pmu_delete_timers(env);
+}
+
+pmu_events_update_cycles(env);
+
+if (env->spr[SPR_P

Re: [PATCH v3] target/riscv: fix VS interrupts forwarding to HS

2021-10-17 Thread Alistair Francis
On Mon, Oct 18, 2021 at 6:30 AM Jose Martins  wrote:
>
> Hello Zhiwei and Alistair,
>
> I noticed this patch did not make it upstream, contrarily to a couple
> other patches I submitted around the same time. Is there something
> else needed from my side to push this forward?

>From your last response I thought you sent a different series that
replaces this patch. If that's not the case do you mind sending this
patch again?

Alistair

>
> Best,
> José
>
> On Wed, 2 Jun 2021 at 20:14, Jose Martins  wrote:
> >
> > Hello Zhiwei and Alistair,
> >
> > I went for a middle-ground solution. I divided the patch into two: one
> > fixes the vs interrupt forwarding to the hypervisor, the other removes
> > the unnecessary force exception stuff. I just submitted the patch
> > series. I hope it's ok with you.
> >
> > José
> >
> > On Fri, 28 May 2021 at 01:36, LIU Zhiwei  wrote:
> > >
> > >
> > > On 5/28/21 6:34 AM, Alistair Francis wrote:
> > > > On Sun, May 23, 2021 at 1:45 AM Jose Martins  
> > > > wrote:
> > > >> VS interrupts (2, 6, 10) were not correctly forwarded to hs-mode when
> > > >> not delegated in hideleg (which was not being taken into account). This
> > > >> was mainly because hs level sie was not always considered enabled when
> > > >> it should. The spec states that "Interrupts for higher-privilege modes,
> > > >> y>x, are always globally enabled regardless of the setting of the 
> > > >> global
> > > >> yIE bit for the higher-privilege mode." and also "For purposes of
> > > >> interrupt global enables, HS-mode is considered more privileged than
> > > >> VS-mode, and VS-mode is considered more privileged than VU-mode".
> > > >>
> > > >> These interrupts should be treated the same as any other kind of
> > > >> exception. Therefore, there is no need to "force an hs exception" as 
> > > >> the
> > > >> current privilege level, the state of the global ie and of the
> > > >> delegation registers should be enough to route the interrupt to the
> > > >> appropriate privilege level in riscv_cpu_do_interrupt. Also, these
> > > >> interrupts never target m-mode, which is  guaranteed by the hardwiring
> > > >> of the corresponding bits in mideleg. The same is true for synchronous
> > > >> exceptions, specifically, guest page faults which must be hardwired in
> > > >> to zero hedeleg. As such the hs_force_except mechanism can be removed.
> > > >>
> > > >> Signed-off-by: Jose Martins 
> > > > This looks right to me, but this was one of the most confusing parts
> > > > of the implementation. I also don't think the patch is too long as
> > > > it's mostly just deleting stuff.
> > > >
> > > > I don't fully understand your concerns Zhiwei, do you mind stating them 
> > > > again?
> > >
> > > Hi Alistair,
> > >
> > > My main concern is the commit message is to complex.
> > >
> > > I also have a question why force hs exception in current code.
> > > Then we can give a brief commit message.
> > >
> > > Best Regards,
> > > Zhiwei
> > >
> > > >
> > > > Alistair
> > > >
> > > >> ---
> > > >> This version of the patch also removes the uneeded hs_force_except
> > > >> functions, variables and macro.
> > > >>
> > > >>   target/riscv/cpu.h|  2 --
> > > >>   target/riscv/cpu_bits.h   |  6 -
> > > >>   target/riscv/cpu_helper.c | 54 
> > > >> +++
> > > >>   3 files changed, 9 insertions(+), 53 deletions(-)
> > > >>
> > > >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > >> index 0a33d387ba..a30a64241a 100644
> > > >> --- a/target/riscv/cpu.h
> > > >> +++ b/target/riscv/cpu.h
> > > >> @@ -337,8 +337,6 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
> > > >> interrupt_request);
> > > >>   bool riscv_cpu_fp_enabled(CPURISCVState *env);
> > > >>   bool riscv_cpu_virt_enabled(CPURISCVState *env);
> > > >>   void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
> > > >> -bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
> > > >> -void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
> > > >>   bool riscv_cpu_two_stage_lookup(int mmu_idx);
> > > >>   int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
> > > >>   hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
> > > >> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > > >> index caf4599207..7322f54157 100644
> > > >> --- a/target/riscv/cpu_bits.h
> > > >> +++ b/target/riscv/cpu_bits.h
> > > >> @@ -462,12 +462,6 @@
> > > >>
> > > >>   /* Virtulisation Register Fields */
> > > >>   #define VIRT_ONOFF  1
> > > >> -/* This is used to save state for when we take an exception. If this 
> > > >> is set
> > > >> - * that means that we want to force a HS level exception (no matter 
> > > >> what the
> > > >> - * delegation is set to). This will occur for things such as a second 
> > > >> level
> > > >> - * page table fault.
> > > >> - */
> > > >> -#define FORCE_HS_EXCEP  2
> > > >>
> > > >>   /* RV32 satp CSR field masks */
> > > >>   #define SATP32_MOD

[PATCH v4 15/15] target/ppc/excp_helper.c: EBB handling adjustments

2021-10-17 Thread Daniel Henrique Barboza
The current logic is only considering event-based exceptions triggered
by the performance monitor. This is true now, but we might want to add
support for external event-based exceptions in the future.

Let's make it a bit easier to do so by adding the bit logic that would
happen in case we were dealing with an external event-based exception.

While we're at it, add a few comments explaining why we're setting and
clearing BESCR bits.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/excp_helper.c | 45 ++--
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 88aa0a84f8..d30020d991 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -798,14 +798,47 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
   "is not implemented yet !\n");
 break;
 case POWERPC_EXCP_EBB:   /* Event-based branch exception */
-if ((env->spr[SPR_BESCR] & BESCR_GE) &&
-(env->spr[SPR_BESCR] & BESCR_PME)) {
+if (env->spr[SPR_BESCR] & BESCR_GE) {
 target_ulong nip;
 
-env->spr[SPR_BESCR] &= ~BESCR_GE;   /* Clear GE */
-env->spr[SPR_BESCR] |= BESCR_PMEO;  /* Set PMEO */
-env->spr[SPR_EBBRR] = env->nip; /* Save NIP for rfebb insn */
-nip = env->spr[SPR_EBBHR];  /* EBB handler */
+/*
+ * If we have Performance Monitor Event-Based exception
+ * enabled (BESCR_PME) and a Performance Monitor alert
+ * occurred (MMCR0_PMAO), clear BESCR_PME and set BESCR_PMEO
+ * (Performance Monitor Event-Based Exception Occurred).
+ *
+ * Software is responsible for clearing both BESCR_PMEO and
+ * MMCR0_PMAO after the event has been handled.
+ */
+if ((env->spr[SPR_BESCR] & BESCR_PME) &&
+(env->spr[SPR_POWER_MMCR0] & MMCR0_PMAO)) {
+env->spr[SPR_BESCR] &= ~BESCR_PME;
+env->spr[SPR_BESCR] |= BESCR_PMEO;
+}
+
+/*
+ * In the case of External Event-Based exceptions, do a
+ * similar logic with BESCR_EE and BESCR_EEO. BESCR_EEO must
+ * also be cleared by software.
+ *
+ * PowerISA 3.1 considers that we'll not have BESCR_PMEO and
+ * BESCR_EEO set at the same time. We can check for BESCR_PMEO
+ * being not set in step above to see if this exception was
+ * trigged by an external event.
+ */
+if (env->spr[SPR_BESCR] & BESCR_EE &&
+!(env->spr[SPR_BESCR] & BESCR_PMEO)) {
+env->spr[SPR_BESCR] &= ~BESCR_EE;
+env->spr[SPR_BESCR] |= BESCR_EEO;
+}
+
+/*
+ * Clear BESCR_GE, save NIP for 'rfebb' and point the
+ * execution to the event handler (SPR_EBBHR) address.
+ */
+env->spr[SPR_BESCR] &= ~BESCR_GE;
+env->spr[SPR_EBBRR] = env->nip;
+nip = env->spr[SPR_EBBHR];
 powerpc_set_excp_state(cpu, nip, env->msr);
 }
 /*
-- 
2.31.1




[PATCH] via-ide: Avoid expensive operations in irq handler

2021-10-17 Thread BALATON Zoltan
Cache the pointer to PCI function 0 (ISA bridge, that this IDE device
has to use for IRQs) in the PCIIDEState and pass that as the opaque
data for the interrupt handler to eliminate both the need to look up
function 0 at every interrupt and also a QOM type cast of the opaque
pointer as that's also expensive (mainly due to qom-debug being
enabled by default).

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 11 ++-
 include/hw/ide/pci.h |  1 +
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 82def819c4..30566bc409 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -104,15 +104,15 @@ static void bmdma_setup_bar(PCIIDEState *d)
 
 static void via_ide_set_irq(void *opaque, int n, int level)
 {
-PCIDevice *d = PCI_DEVICE(opaque);
+PCIIDEState *d = opaque;
 
 if (level) {
-d->config[0x70 + n * 8] |= 0x80;
+d->parent_obj.config[0x70 + n * 8] |= 0x80;
 } else {
-d->config[0x70 + n * 8] &= ~0x80;
+d->parent_obj.config[0x70 + n * 8] &= ~0x80;
 }
 
-via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
+via_isa_set_irq(d->func0, 14 + n, level);
 }
 
 static void via_ide_reset(DeviceState *dev)
@@ -188,7 +188,8 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
 bmdma_setup_bar(d);
 pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
-qdev_init_gpio_in(ds, via_ide_set_irq, 2);
+d->func0 = pci_get_function_0(dev);
+qdev_init_gpio_in_named_with_opaque(ds, via_ide_set_irq, d, NULL, 2);
 for (i = 0; i < 2; i++) {
 ide_bus_init(&d->bus[i], sizeof(d->bus[i]), ds, i, 2);
 ide_init2(&d->bus[i], qdev_get_gpio_in(ds, i));
diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index d8384e1c42..89d14abf95 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -50,6 +50,7 @@ struct PCIIDEState {
 IDEBus bus[2];
 BMDMAState bmdma[2];
 uint32_t secondary; /* used only for cmd646 */
+PCIDevice *func0; /* used only by IDE functions of superio chips */
 MemoryRegion bmdma_bar;
 MemoryRegion cmd_bar[2];
 MemoryRegion data_bar[2];
-- 
2.21.4




Re: [PATCH v3 1/6] target/riscv: zfh: half-precision load and store

2021-10-17 Thread Frank Chang
On Mon, Oct 18, 2021 at 8:03 AM Alistair Francis 
wrote:

> On Sat, Oct 16, 2021 at 7:08 PM  wrote:
> >
> > From: Kito Cheng 
> >
> > Signed-off-by: Kito Cheng 
> > Signed-off-by: Chih-Min Chao 
> > Signed-off-by: Frank Chang 
> > Reviewed-by: Richard Henderson 
> > ---
> >  target/riscv/cpu.c|  1 +
> >  target/riscv/cpu.h|  1 +
> >  target/riscv/insn32.decode|  4 ++
> >  target/riscv/insn_trans/trans_rvzfh.c.inc | 65 +++
> >  target/riscv/translate.c  |  8 +++
> >  5 files changed, 79 insertions(+)
> >  create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 1d69d1887e6..8c579dc297b 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -601,6 +601,7 @@ static Property riscv_cpu_properties[] = {
> >  DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
> >  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),
>
> This change should be after patch 5. The idea is that we add the
> functionality and then allow users to enable it.
>
> Otherwise:
>
> Reviewed-by: Alistair Francis 
>
> Alistair
>

The reason why I put here is because REQUIRE_ZFH() uses ctx->zfh.
I can separate ext_zfh field in DisasContext into this patch,
and add cfg.ext_zfh in RISCVCPU after patch 5 in my next patchset.

Thanks,
Frank Chang


>
> >  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> >  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> >  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 9e55b2f5b17..88684e72be1 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -297,6 +297,7 @@ struct RISCVCPU {
> >  bool ext_counters;
> >  bool ext_ifencei;
> >  bool ext_icsr;
> > +bool ext_zfh;
> >
> >  char *priv_spec;
> >  char *user_spec;
> > diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> > index 2f251dac1bb..b36a3d8dbf8 100644
> > --- a/target/riscv/insn32.decode
> > +++ b/target/riscv/insn32.decode
> > @@ -726,3 +726,7 @@ binv   0110100 .. 001 . 0110011 @r
> >  binvi  01101. ... 001 . 0010011 @sh
> >  bset   0010100 .. 001 . 0110011 @r
> >  bseti  00101. ... 001 . 0010011 @sh
> > +
> > +# *** RV32 Zfh Extension ***
> > +flh   . 001 . 111 @i
> > +fsh...  . . 001 . 0100111 @s
> > diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc
> b/target/riscv/insn_trans/trans_rvzfh.c.inc
> > new file mode 100644
> > index 000..dad1d703d72
> > --- /dev/null
> > +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> > @@ -0,0 +1,65 @@
> > +/*
> > + * RISC-V translation routines for the RV64Zfh Standard Extension.
> > + *
> > + * Copyright (c) 2020 Chih-Min Chao, chihmin.c...@sifive.com
> > + *
> > + * 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 .
> > + */
> > +
> > +#define REQUIRE_ZFH(ctx) do { \
> > +if (!ctx->ext_zfh) {  \
> > +return false; \
> > +} \
> > +} while (0)
> > +
> > +static bool trans_flh(DisasContext *ctx, arg_flh *a)
> > +{
> > +TCGv_i64 dest;
> > +TCGv t0;
> > +
> > +REQUIRE_FPU;
> > +REQUIRE_ZFH(ctx);
> > +
> > +t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> > +if (a->imm) {
> > +TCGv temp = temp_new(ctx);
> > +tcg_gen_addi_tl(temp, t0, a->imm);
> > +t0 = temp;
> > +}
> > +
> > +dest = cpu_fpr[a->rd];
> > +tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TEUW);
> > +gen_nanbox_h(dest, dest);
> > +
> > +mark_fs_dirty(ctx);
> > +return true;
> > +}
> > +
> > +static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
> > +{
> > +TCGv t0;
> > +
> > +REQUIRE_FPU;
> > +REQUIRE_ZFH(ctx);
> > +
> > +t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> > +if (a->imm) {
> > +TCGv temp = tcg_temp_new();
> > +tcg_gen_addi_tl(temp, t0, a->imm);
> > +t0 = temp;
> > +}
> > +
> > +tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW);

Re: [PATCH v2] hw/riscv: virt: bugfix the memory-backend-file command is invalid

2021-10-17 Thread Bin Meng
Hi Igor,

On Fri, Oct 15, 2021 at 8:59 PM Igor Mammedov  wrote:
>
> On Fri, 15 Oct 2021 17:25:01 +0800
> Bin Meng  wrote:
>
> > On Fri, Oct 15, 2021 at 4:52 PM limingwang (A)  
> > wrote:
> > >
> > >
> > > On Wed, Oct 13, 2021 at 22:41 PM Bin Meng  wrote:
> > > >
> > > > On Tue, Oct 12, 2021 at 9:46 AM MingWang Li  
> > > > wrote:
> > > > >
> > > > > From: Mingwang Li 
> > > > >
> > > > > When I start the VM with the following command:
> > > > > $ ./qemu-system-riscv64 -M virt,accel=kvm -m 4096M -cpu host 
> > > > > -nographic \
> > > > > -name guest=riscv-guset \
> > > > > -smp 2 \
> > > > > -bios none \
> > > > > -kernel ./Image \
> > > > > -drive file=./guest.img,format=raw,id=hd0 \
> > > > > -device virtio-blk-device,drive=hd0 \
> > > > > -append "root=/dev/vda rw console=ttyS0 earlycon=sbi" \
> > > > > -object
> > > > memory-backend-file,id=mem,size=4096M,mem-path=/dev/hugepages,share=on \
> > > > > -numa node,memdev=mem -mem-prealloc \
> > > > > -chardev socket,id=char0,path=/mnt/vhost-net0 \
> > > > > -netdev type=vhost-user,id=mynet1,chardev=char0,vhostforce \
> > > > > -device
> > > > > virtio-net-pci,mac=52:54:00:00:00:01,netdev=mynet1,mrg_rxbuf=on,csum=o
> > > > > n,guest_csum=on,guest_ecn=on \
> > > > >
> > > > > Then, QEMU displays the following error information:
> > > > > qemu-system-riscv64: Failed initializing vhost-user memory map,
> > > > > consider using -object memory-backend-file share=on
> > > >
> > > > I see your command line parameters already contain "-object 
> > > > memory-backend-file
> > > > share=on", so this error message is not accurate.
> > >
> > > QEMU uses this command to alloc fd in the 
> > > "memory_region_init_ram_from_file" function
> > > and assigns the value of fd to mr->ram_block-fd. If the QEMU uses the 
> > > default memory to
> > > initialize the system, the QEMU cannot obtain the fd in the 
> > > "vhost_user_mem_section_filter"
> > > function when initializing the vhost-user. As a result, an error is 
> > > reported in the "vhost_user_fill_set_mem_table_msg"
> > > function.
> > >
> > > Because of the above bug, even if "-object memory-backend-file share=on" 
> > > is added to the command line,
> > > the QEMU still reports an error.
> >
> > Yes, what I meant is that QEMU should not report such inaccurate
> > messages because of some random codes elsewhere.
> >
> > With current message, it suggested user use "-object
> > memory-backend-file share=on" in the command line, but it is already
> > used. So this is a false alarm. The "bug" is somewhere else.
>
> bug is in using memory_region_init_ram(),
> which can't possibly handle vhost-user, and can't work as expected with
> '-numa node,memdev' options.
> Before main ram infrastructure was converted to memdev,
> one should have used memory_region_allocate_system_memory() for
> allocating main RAM, so numa usecase was broken from the start.
> Later it old API was dropped in favor of more flexible/generic
> MachineState::ram approach (see commits 68a86dc15ccd..f0530f14c7c35d).

Thanks for the detailed pointers.

I wonder if it is possible to make the error message to be clearer, so
instead of having

"qemu-system-riscv64: Failed initializing vhost-user memory map,
consider using -object memory-backend-file share=on"

can we do:

"qemu-system-riscv64: Failed initializing vhost-user memory map,
considering using MachineState::ram instead of manually initializing
RAM memory region."

which is more straightforward?

>
>
> Modulo commit message, patch looks good to me and does what
> every machine should do. (I though that I've converted every
> existing to generalized MachineState::ram but it looks like
> riscv was missed).

Indeed all riscv boards are doing the same thing.

>
> So we can model commit message after bd457782b3b0a,
> and also add that the patch fixes broken -numa node,memdev case,
> which never properly worked. It also opens possibility to
> use vhost-user/virtiosf with main RAM if main RAM is
> provided explicitly via machine.memory-backend option
> with shared memory backend.
>
> Btw: is there other riscv machines that allocate RAM directly?
> (if yes, those should be fixed as well, a patch per machine)
>

I will see if I can get some patches to fix other riscv machines.

Regards,
Bin



[PATCH v1 1/9] hw/riscv: opentitan: Update to the latest build

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Update the OpenTitan machine model to match the latest OpenTitan FPGA
design.

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h |  6 +++---
 hw/riscv/opentitan.c | 22 +-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 9f93bebdac..eac35ef590 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -20,7 +20,7 @@
 #define HW_OPENTITAN_H
 
 #include "hw/riscv/riscv_hart.h"
-#include "hw/intc/ibex_plic.h"
+#include "hw/intc/sifive_plic.h"
 #include "hw/char/ibex_uart.h"
 #include "hw/timer/ibex_timer.h"
 #include "qom/object.h"
@@ -34,7 +34,7 @@ struct LowRISCIbexSoCState {
 
 /*< public >*/
 RISCVHartArrayState cpus;
-IbexPlicState plic;
+SiFivePLICState plic;
 IbexUartState uart;
 IbexTimerState timer;
 
@@ -87,7 +87,7 @@ enum {
 };
 
 enum {
-IBEX_TIMER_TIMEREXPIRED0_0 = 125,
+IBEX_TIMER_TIMEREXPIRED0_0 = 126,
 IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
 IBEX_UART0_RX_TIMEOUT_IRQ = 7,
 IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 9803ae6d70..601f8deebe 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -46,19 +46,19 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_PINMUX] = {  0x4046,  0x1000  },
 [IBEX_DEV_PADCTRL] ={  0x4047,  0x1000  },
 [IBEX_DEV_FLASH_CTRL] = {  0x4100,  0x1000  },
-[IBEX_DEV_PLIC] =   {  0x4101,  0x1000  },
 [IBEX_DEV_AES] ={  0x4110,  0x1000  },
 [IBEX_DEV_HMAC] =   {  0x4111,  0x1000  },
 [IBEX_DEV_KMAC] =   {  0x4112,  0x1000  },
-[IBEX_DEV_KEYMGR] = {  0x4113,  0x1000  },
+[IBEX_DEV_OTBN] =   {  0x4113,  0x1 },
+[IBEX_DEV_KEYMGR] = {  0x4114,  0x1000  },
 [IBEX_DEV_CSRNG] =  {  0x4115,  0x1000  },
 [IBEX_DEV_ENTROPY] ={  0x4116,  0x1000  },
 [IBEX_DEV_EDNO] =   {  0x4117,  0x1000  },
 [IBEX_DEV_EDN1] =   {  0x4118,  0x1000  },
 [IBEX_DEV_ALERT_HANDLER] =  {  0x411b,  0x1000  },
 [IBEX_DEV_NMI_GEN] ={  0x411c,  0x1000  },
-[IBEX_DEV_OTBN] =   {  0x411d,  0x1 },
 [IBEX_DEV_PERI] =   {  0x411f,  0x1 },
+[IBEX_DEV_PLIC] =   {  0x4800,  0x4005000  },
 [IBEX_DEV_FLASH_VIRTUAL] =  {  0x8000,  0x8 },
 };
 
@@ -105,7 +105,7 @@ static void lowrisc_ibex_soc_init(Object *obj)
 
 object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
 
-object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
+object_initialize_child(obj, "plic", &s->plic, TYPE_SIFIVE_PLIC);
 
 object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
 
@@ -145,6 +145,18 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 &s->flash_alias);
 
 /* PLIC */
+qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
+qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
+qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
+qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
+qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
+qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
+qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
+qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 0x18);
+qdev_prop_set_uint32(DEVICE(&s->plic), "context-base", 0x24);
+qdev_prop_set_uint32(DEVICE(&s->plic), "context-stride", 4);
+qdev_prop_set_uint32(DEVICE(&s->plic), "aperture-size", 
memmap[IBEX_DEV_PLIC].size);
+
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->plic), errp)) {
 return;
 }
@@ -153,7 +165,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 for (i = 0; i < ms->smp.cpus; i++) {
 CPUState *cpu = qemu_get_cpu(i);
 
-qdev_connect_gpio_out(DEVICE(&s->plic), i,
+qdev_connect_gpio_out(DEVICE(&s->plic), ms->smp.cpus + i,
   qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
 }
 
-- 
2.31.1




[PATCH v1 2/9] hw/intc: Remove the Ibex PLIC

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

The Ibex PLIC is now spec complient. Let's remove the Ibex PLIC and
instead use the SiFive PLIC.

Signed-off-by: Alistair Francis 
---
 hw/intc/ibex_plic.c | 307 
 hw/intc/meson.build |   1 -
 2 files changed, 308 deletions(-)
 delete mode 100644 hw/intc/ibex_plic.c

diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
deleted file mode 100644
index ff430356f8..00
--- a/hw/intc/ibex_plic.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * QEMU RISC-V lowRISC Ibex PLIC
- *
- * Copyright (c) 2020 Western Digital
- *
- * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
- *
- * 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/log.h"
-#include "hw/qdev-properties.h"
-#include "hw/core/cpu.h"
-#include "hw/boards.h"
-#include "hw/pci/msi.h"
-#include "target/riscv/cpu_bits.h"
-#include "target/riscv/cpu.h"
-#include "hw/intc/ibex_plic.h"
-#include "hw/irq.h"
-
-static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
-{
-uint32_t end = base + (num * 0x04);
-
-if (addr >= base && addr < end) {
-return true;
-}
-
-return false;
-}
-
-static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
-{
-int pending_num = irq / 32;
-
-if (!level) {
-/*
- * If the level is low make sure we clear the hidden_pending.
- */
-s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
-}
-
-if (s->claimed[pending_num] & 1 << (irq % 32)) {
-/*
- * The interrupt has been claimed, but not completed.
- * The pending bit can't be set.
- * Save the pending level for after the interrupt is completed.
- */
-s->hidden_pending[pending_num] |= level << (irq % 32);
-} else {
-s->pending[pending_num] |= level << (irq % 32);
-}
-}
-
-static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
-{
-int i;
-uint32_t max_irq = 0;
-uint32_t max_prio = s->threshold;
-
-for (i = 0; i < s->pending_num; i++) {
-uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
-
-if (!(s->pending[i] & s->enable[i])) {
-/* No pending and enabled IRQ */
-continue;
-}
-
-if (s->priority[irq_num] > max_prio) {
-max_irq = irq_num;
-max_prio = s->priority[irq_num];
-}
-}
-
-if (max_irq) {
-s->claim = max_irq;
-return true;
-}
-
-return false;
-}
-
-static void ibex_plic_update(IbexPlicState *s)
-{
-int i;
-
-for (i = 0; i < s->num_cpus; i++) {
-qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
-}
-}
-
-static void ibex_plic_reset(DeviceState *dev)
-{
-IbexPlicState *s = IBEX_PLIC(dev);
-
-s->threshold = 0x;
-s->claim = 0x;
-}
-
-static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
-   unsigned int size)
-{
-IbexPlicState *s = opaque;
-int offset;
-uint32_t ret = 0;
-
-if (addr_between(addr, s->pending_base, s->pending_num)) {
-offset = (addr - s->pending_base) / 4;
-ret = s->pending[offset];
-} else if (addr_between(addr, s->source_base, s->source_num)) {
-qemu_log_mask(LOG_UNIMP,
-  "%s: Interrupt source mode not supported\n", __func__);
-} else if (addr_between(addr, s->priority_base, s->priority_num)) {
-offset = (addr - s->priority_base) / 4;
-ret = s->priority[offset];
-} else if (addr_between(addr, s->enable_base, s->enable_num)) {
-offset = (addr - s->enable_base) / 4;
-ret = s->enable[offset];
-} else if (addr_between(addr, s->threshold_base, 1)) {
-ret = s->threshold;
-} else if (addr_between(addr, s->claim_base, 1)) {
-int pending_num = s->claim / 32;
-s->pending[pending_num] &= ~(1 << (s->claim % 32));
-
-/* Set the interrupt as claimed, but not completed */
-s->claimed[pending_num] |= 1 << (s->claim % 32);
-
-/* Return the current claimed interrupt */
-ret = s->claim;
-
-/* Clear the claimed interrupt */
-s->claim = 0x;
-
-/* Update the interrupt status after the claim */
-ibex_plic_update(s);
-}
-
-return ret;
-}
-
-static void ibex_plic_write(void *opaque, hwaddr a

[PATCH v1 5/9] hw/intc: sifive_plic: Cleanup the irq_request function

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index d77a5ced23..877e76877c 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -412,12 +412,10 @@ static void parse_hart_config(SiFivePLICState *plic)
 
 static void sifive_plic_irq_request(void *opaque, int irq, int level)
 {
-SiFivePLICState *plic = opaque;
-if (RISCV_DEBUG_PLIC) {
-qemu_log("sifive_plic_irq_request: irq=%d level=%d\n", irq, level);
-}
-sifive_plic_set_pending(plic, irq, level > 0);
-sifive_plic_update(plic);
+SiFivePLICState *s = opaque;
+
+sifive_plic_set_pending(s, irq, level > 0);
+sifive_plic_update(s);
 }
 
 static void sifive_plic_realize(DeviceState *dev, Error **errp)
-- 
2.31.1




[PATCH v1 6/9] hw/intc: sifive_plic: Add a reset function

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 877e76877c..5444368ad4 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -355,6 +355,18 @@ static const MemoryRegionOps sifive_plic_ops = {
 }
 };
 
+static void sifive_plic_reset(DeviceState *dev)
+{
+SiFivePLICState *s = SIFIVE_PLIC(dev);
+
+memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words);
+memset(s->source_priority, 0, sizeof(uint32_t) * s->num_sources);
+memset(s->target_priority, 0, sizeof(uint32_t) * s->num_addrs);
+memset(s->pending, 0, sizeof(uint32_t) * s->bitfield_words);
+memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words);
+memset(s->enable, 0, sizeof(uint32_t) * s->num_enables);
+}
+
 /*
  * parse PLIC hart/mode address offset config
  *
@@ -501,6 +513,7 @@ static void sifive_plic_class_init(ObjectClass *klass, void 
*data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
+dc->reset = sifive_plic_reset;
 device_class_set_props(dc, sifive_plic_properties);
 dc->realize = sifive_plic_realize;
 dc->vmsd = &vmstate_sifive_plic;
-- 
2.31.1




[PATCH v1 3/9] hw/intc: sifive_plic: Move the properties

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 9ba36dc0b3..f0e2799efc 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -355,21 +355,6 @@ static const MemoryRegionOps sifive_plic_ops = {
 }
 };
 
-static Property sifive_plic_properties[] = {
-DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
-DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
-DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
-DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
-DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
-DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
-DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
-DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
-DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
-DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
-DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
-DEFINE_PROP_END_OF_LIST(),
-};
-
 /*
  * parse PLIC hart/mode address offset config
  *
@@ -496,6 +481,21 @@ static const VMStateDescription vmstate_sifive_plic = {
 }
 };
 
+static Property sifive_plic_properties[] = {
+DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
+DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
+DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
+DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
+DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
+DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
+DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
+DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
+DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
+DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
+DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void sifive_plic_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
-- 
2.31.1




[PATCH v1 4/9] hw/intc: sifive_plic: Cleanup the realize function

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 45 +++
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index f0e2799efc..d77a5ced23 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -422,35 +422,38 @@ static void sifive_plic_irq_request(void *opaque, int 
irq, int level)
 
 static void sifive_plic_realize(DeviceState *dev, Error **errp)
 {
-SiFivePLICState *plic = SIFIVE_PLIC(dev);
+SiFivePLICState *s = SIFIVE_PLIC(dev);
 int i;
 
-memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
-  TYPE_SIFIVE_PLIC, plic->aperture_size);
-parse_hart_config(plic);
-plic->bitfield_words = (plic->num_sources + 31) >> 5;
-plic->num_enables = plic->bitfield_words * plic->num_addrs;
-plic->source_priority = g_new0(uint32_t, plic->num_sources);
-plic->target_priority = g_new(uint32_t, plic->num_addrs);
-plic->pending = g_new0(uint32_t, plic->bitfield_words);
-plic->claimed = g_new0(uint32_t, plic->bitfield_words);
-plic->enable = g_new0(uint32_t, plic->num_enables);
-sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
-qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
-
-plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
-qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
-
-plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
-qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
+memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_plic_ops, s,
+  TYPE_SIFIVE_PLIC, s->aperture_size);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
+
+parse_hart_config(s);
+
+s->bitfield_words = (s->num_sources + 31) >> 5;
+s->num_enables = s->bitfield_words * s->num_addrs;
+s->source_priority = g_new0(uint32_t, s->num_sources);
+s->target_priority = g_new(uint32_t, s->num_addrs);
+s->pending = g_new0(uint32_t, s->bitfield_words);
+s->claimed = g_new0(uint32_t, s->bitfield_words);
+s->enable = g_new0(uint32_t, s->num_enables);
+
+qdev_init_gpio_in(dev, sifive_plic_irq_request, s->num_sources);
+
+s->s_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+qdev_init_gpio_out(dev, s->s_external_irqs, s->num_harts);
+
+s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
 
 /* We can't allow the supervisor to control SEIP as this would allow the
  * supervisor to clear a pending external interrupt which will result in
  * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
  * hardware controlled when a PLIC is attached.
  */
-for (i = 0; i < plic->num_harts; i++) {
-RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(plic->hartid_base + i));
+for (i = 0; i < s->num_harts; i++) {
+RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
 if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
 error_report("SEIP already claimed");
 exit(1);
-- 
2.31.1




[PATCH v1 9/9] hw/intc: sifive_plic: Cleanup remaining functions

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 109 +-
 1 file changed, 22 insertions(+), 87 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index d73503cea4..3f56223554 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -31,8 +31,6 @@
 #include "migration/vmstate.h"
 #include "hw/irq.h"
 
-#define RISCV_DEBUG_PLIC 0
-
 static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
 {
 uint32_t end = base + num;
@@ -57,47 +55,6 @@ static PLICMode char_to_mode(char c)
 }
 }
 
-static char mode_to_char(PLICMode m)
-{
-switch (m) {
-case PLICMode_U: return 'U';
-case PLICMode_S: return 'S';
-case PLICMode_H: return 'H';
-case PLICMode_M: return 'M';
-default: return '?';
-}
-}
-
-static void sifive_plic_print_state(SiFivePLICState *plic)
-{
-int i;
-int addrid;
-
-/* pending */
-qemu_log("pending   : ");
-for (i = plic->bitfield_words - 1; i >= 0; i--) {
-qemu_log("%08x", plic->pending[i]);
-}
-qemu_log("\n");
-
-/* pending */
-qemu_log("claimed   : ");
-for (i = plic->bitfield_words - 1; i >= 0; i--) {
-qemu_log("%08x", plic->claimed[i]);
-}
-qemu_log("\n");
-
-for (addrid = 0; addrid < plic->num_addrs; addrid++) {
-qemu_log("hart%d-%c enable: ",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode));
-for (i = plic->bitfield_words - 1; i >= 0; i--) {
-qemu_log("%08x", plic->enable[addrid * plic->bitfield_words + i]);
-}
-qemu_log("\n");
-}
-}
-
 static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value)
 {
 uint32_t old, new, cmp = qatomic_read(a);
@@ -121,26 +78,34 @@ static void sifive_plic_set_claimed(SiFivePLICState *plic, 
int irq, bool level)
 atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level);
 }
 
-static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
+static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
 {
+uint32_t max_irq = 0;
+uint32_t max_prio = plic->target_priority[addrid];
 int i, j;
+
 for (i = 0; i < plic->bitfield_words; i++) {
 uint32_t pending_enabled_not_claimed =
-(plic->pending[i] & ~plic->claimed[i]) &
-plic->enable[addrid * plic->bitfield_words + i];
+(plic->pending[i] & ~plic->claimed[i]) &
+plic->enable[addrid * plic->bitfield_words + i];
+
 if (!pending_enabled_not_claimed) {
 continue;
 }
+
 for (j = 0; j < 32; j++) {
 int irq = (i << 5) + j;
 uint32_t prio = plic->source_priority[irq];
 int enabled = pending_enabled_not_claimed & (1 << j);
-if (enabled && prio > plic->target_priority[addrid]) {
-return 1;
+
+if (enabled && prio > max_prio) {
+max_irq = irq;
+max_prio = prio;
 }
 }
 }
-return 0;
+
+return max_irq;
 }
 
 static void sifive_plic_update(SiFivePLICState *plic)
@@ -151,7 +116,7 @@ static void sifive_plic_update(SiFivePLICState *plic)
 for (addrid = 0; addrid < plic->num_addrs; addrid++) {
 uint32_t hartid = plic->addr_config[addrid].hartid;
 PLICMode mode = plic->addr_config[addrid].mode;
-int level = sifive_plic_irqs_pending(plic, addrid);
+bool level = !!sifive_plic_claimed(plic, addrid);
 
 switch (mode) {
 case PLICMode_M:
@@ -164,41 +129,6 @@ static void sifive_plic_update(SiFivePLICState *plic)
 break;
 }
 }
-
-if (RISCV_DEBUG_PLIC) {
-sifive_plic_print_state(plic);
-}
-}
-
-static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
-{
-int i, j;
-uint32_t max_irq = 0;
-uint32_t max_prio = plic->target_priority[addrid];
-
-for (i = 0; i < plic->bitfield_words; i++) {
-uint32_t pending_enabled_not_claimed =
-(plic->pending[i] & ~plic->claimed[i]) &
-plic->enable[addrid * plic->bitfield_words + i];
-if (!pending_enabled_not_claimed) {
-continue;
-}
-for (j = 0; j < 32; j++) {
-int irq = (i << 5) + j;
-uint32_t prio = plic->source_priority[irq];
-int enabled = pending_enabled_not_claimed & (1 << j);
-if (enabled && prio > max_prio) {
-max_irq = irq;
-max_prio = prio;
-}
-}
-}
-
-if (max_irq) {
-sifive_plic_set_pending(plic, max_irq, false);
-sifive_plic_set_claimed(plic, max_irq, true);
-}
-return max_irq;
 }
 
 static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
@@ -229,10 +159,15 @@ static uint64_t sifive_plic_read(void *opaque, hw

[PATCH v1 7/9] hw/intc: sifive_plic: Cleanup the write function

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 82 +--
 1 file changed, 33 insertions(+), 49 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 5444368ad4..49e566a76f 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -33,6 +33,17 @@
 
 #define RISCV_DEBUG_PLIC 0
 
+static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
+{
+uint32_t end = base + num;
+
+if (addr >= base && addr < end) {
+return true;
+}
+
+return false;
+}
+
 static PLICMode char_to_mode(char c)
 {
 switch (c) {
@@ -269,80 +280,53 @@ static void sifive_plic_write(void *opaque, hwaddr addr, 
uint64_t value,
 {
 SiFivePLICState *plic = opaque;
 
-/* writes must be 4 byte words */
-if ((addr & 0x3) != 0) {
-goto err;
-}
-
-if (addr >= plic->priority_base && /* 4 bytes per source */
-addr < plic->priority_base + (plic->num_sources << 2))
-{
+if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
 uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
+
 plic->source_priority[irq] = value & 7;
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: write priority: irq=%d priority=%d\n",
-irq, plic->source_priority[irq]);
-}
 sifive_plic_update(plic);
-return;
-} else if (addr >= plic->pending_base && /* 1 bit per source */
-   addr < plic->pending_base + (plic->num_sources >> 3))
-{
+} else if (addr_between(addr, plic->pending_base,
+plic->num_sources >> 3)) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: invalid pending write: 0x%" HWADDR_PRIx "",
   __func__, addr);
-return;
-} else if (addr >= plic->enable_base && /* 1 bit per source */
-addr < plic->enable_base + plic->num_addrs * plic->enable_stride)
-{
+} else if (addr_between(addr, plic->enable_base,
+plic->num_addrs * plic->enable_stride)) {
 uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride;
 uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2;
+
 if (wordid < plic->bitfield_words) {
 plic->enable[addrid * plic->bitfield_words + wordid] = value;
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: write enable: hart%d-%c word=%d value=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode), wordid,
-plic->enable[addrid * plic->bitfield_words + wordid]);
-}
-return;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Invalid enable write 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
 }
-} else if (addr >= plic->context_base && /* 4 bytes per reg */
-addr < plic->context_base + plic->num_addrs * plic->context_stride)
-{
+} else if (addr_between(addr, plic->context_base,
+plic->num_addrs * plic->context_stride)) {
 uint32_t addrid = (addr - plic->context_base) / plic->context_stride;
 uint32_t contextid = (addr & (plic->context_stride - 1));
+
 if (contextid == 0) {
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: write priority: hart%d-%c priority=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode),
-plic->target_priority[addrid]);
-}
 if (value <= plic->num_priorities) {
 plic->target_priority[addrid] = value;
 sifive_plic_update(plic);
 }
-return;
 } else if (contextid == 4) {
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: write claim: hart%d-%c irq=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode),
-(uint32_t)value);
-}
 if (value < plic->num_sources) {
 sifive_plic_set_claimed(plic, value, false);
 sifive_plic_update(plic);
 }
-return;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Invalid context write 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
 }
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Invalid register write 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
 }
-
-err:
-qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: Invalid register write 0x%" HWADDR_PRIx "\n",
-  __func__, addr);
 }
 
 static const MemoryRegionOps sifive_plic_ops = {
-- 
2.31.1




[PATCH v1 8/9] hw/intc: sifive_plic: Cleanup the read function

2021-10-17 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 55 +--
 1 file changed, 11 insertions(+), 44 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 49e566a76f..d73503cea4 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -205,70 +205,37 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr 
addr, unsigned size)
 {
 SiFivePLICState *plic = opaque;
 
-/* writes must be 4 byte words */
-if ((addr & 0x3) != 0) {
-goto err;
-}
-
-if (addr >= plic->priority_base && /* 4 bytes per source */
-addr < plic->priority_base + (plic->num_sources << 2))
-{
+if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
 uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: read priority: irq=%d priority=%d\n",
-irq, plic->source_priority[irq]);
-}
+
 return plic->source_priority[irq];
-} else if (addr >= plic->pending_base && /* 1 bit per source */
-   addr < plic->pending_base + (plic->num_sources >> 3))
-{
+} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) 
{
 uint32_t word = (addr - plic->pending_base) >> 2;
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: read pending: word=%d value=%d\n",
-word, plic->pending[word]);
-}
+
 return plic->pending[word];
-} else if (addr >= plic->enable_base && /* 1 bit per source */
- addr < plic->enable_base + plic->num_addrs * plic->enable_stride)
-{
+} else if (addr_between(addr, plic->enable_base,
+plic->num_addrs * plic->enable_stride)) {
 uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride;
 uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2;
+
 if (wordid < plic->bitfield_words) {
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: read enable: hart%d-%c word=%d value=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode), wordid,
-plic->enable[addrid * plic->bitfield_words + wordid]);
-}
 return plic->enable[addrid * plic->bitfield_words + wordid];
 }
-} else if (addr >= plic->context_base && /* 1 bit per source */
- addr < plic->context_base + plic->num_addrs * 
plic->context_stride)
-{
+} else if (addr_between(addr, plic->context_base,
+plic->num_addrs * plic->context_stride)) {
 uint32_t addrid = (addr - plic->context_base) / plic->context_stride;
 uint32_t contextid = (addr & (plic->context_stride - 1));
+
 if (contextid == 0) {
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: read priority: hart%d-%c priority=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode),
-plic->target_priority[addrid]);
-}
 return plic->target_priority[addrid];
 } else if (contextid == 4) {
 uint32_t value = sifive_plic_claim(plic, addrid);
-if (RISCV_DEBUG_PLIC) {
-qemu_log("plic: read claim: hart%d-%c irq=%x\n",
-plic->addr_config[addrid].hartid,
-mode_to_char(plic->addr_config[addrid].mode),
-value);
-}
+
 sifive_plic_update(plic);
 return value;
 }
 }
 
-err:
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: Invalid register read 0x%" HWADDR_PRIx "\n",
   __func__, addr);
-- 
2.31.1




Re: [PATCH] target/ppc: Filter mtmsr[d] input before setting MSR

2021-10-17 Thread David Gibson
On Fri, Oct 15, 2021 at 03:19:40PM -0300, matheus.fe...@eldorado.org.br wrote:
> From: Matheus Ferst 
> 
> PowerISA says that mtmsr[d] "does not alter MSR[HV], MSR[S], MSR[ME], or
> MSR[LE]", but the current code only filters the GPR-provided value if
> L=1. This behavior caused some problems in FreeBSD, and a build option
> was added to work around the issue [1], but it seems that the bug was
> not reported in launchpad/gitlab. This patch address the issue in qemu,
> so the option on FreeBSD should no longer be required.
> 
> [1] 
> https://cgit.freebsd.org/src/commit/?id=4efb1ca7d2a44cfb33d7f9e18bd92f8d68dcfee0
> 
> Signed-off-by: Matheus Ferst 

Applied to ppc-for-6.2, thanks.

> ---
>  target/ppc/cpu.h   |  1 +
>  target/ppc/translate.c | 73 +++---
>  2 files changed, 41 insertions(+), 33 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index baa4e7c34d..e94e82297b 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -314,6 +314,7 @@ typedef struct ppc_v3_pate_t {
>  #define MSR_AP   23 /* Access privilege state on 602  hflags 
> */
>  #define MSR_VSX  23 /* Vector Scalar Extension (ISA 2.06 and later) x hflags 
> */
>  #define MSR_SA   22 /* Supervisor access mode on 602  hflags 
> */
> +#define MSR_S22 /* Secure state  
> */
>  #define MSR_KEY  19 /* key bit on 603e   
> */
>  #define MSR_POW  18 /* Power management  
> */
>  #define MSR_TGPR 17 /* TGPR usage on 602/603x
> */
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index b985e9e55b..a5ebe03e2a 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4940,32 +4940,40 @@ static void gen_mtmsrd(DisasContext *ctx)
>  CHK_SV;
>  
>  #if !defined(CONFIG_USER_ONLY)
> +TCGv t0, t1;
> +target_ulong mask;
> +
> +t0 = tcg_temp_new();
> +t1 = tcg_temp_new();
> +
>  gen_icount_io_start(ctx);
> +
>  if (ctx->opcode & 0x0001) {
>  /* L=1 form only updates EE and RI */
> -TCGv t0 = tcg_temp_new();
> -TCGv t1 = tcg_temp_new();
> -tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
> -(1 << MSR_RI) | (1 << MSR_EE));
> -tcg_gen_andi_tl(t1, cpu_msr,
> -~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
> -tcg_gen_or_tl(t1, t1, t0);
> -
> -gen_helper_store_msr(cpu_env, t1);
> -tcg_temp_free(t0);
> -tcg_temp_free(t1);
> -
> +mask = (1ULL << MSR_RI) | (1ULL << MSR_EE);
>  } else {
> +/* mtmsrd does not alter HV, S, ME, or LE */
> +mask = ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S) |
> + (1ULL << MSR_HV));
>  /*
>   * XXX: we need to update nip before the store if we enter
>   *  power saving mode, we will exit the loop directly from
>   *  ppc_store_msr
>   */
>  gen_update_nip(ctx, ctx->base.pc_next);
> -gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
>  }
> +
> +tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], mask);
> +tcg_gen_andi_tl(t1, cpu_msr, ~mask);
> +tcg_gen_or_tl(t0, t0, t1);
> +
> +gen_helper_store_msr(cpu_env, t0);
> +
>  /* Must stop the translation as machine state (may have) changed */
>  ctx->base.is_jmp = DISAS_EXIT_UPDATE;
> +
> +tcg_temp_free(t0);
> +tcg_temp_free(t1);
>  #endif /* !defined(CONFIG_USER_ONLY) */
>  }
>  #endif /* defined(TARGET_PPC64) */
> @@ -4975,23 +4983,19 @@ static void gen_mtmsr(DisasContext *ctx)
>  CHK_SV;
>  
>  #if !defined(CONFIG_USER_ONLY)
> +TCGv t0, t1;
> +target_ulong mask = 0x;
> +
> +t0 = tcg_temp_new();
> +t1 = tcg_temp_new();
> +
>  gen_icount_io_start(ctx);
>  if (ctx->opcode & 0x0001) {
>  /* L=1 form only updates EE and RI */
> -TCGv t0 = tcg_temp_new();
> -TCGv t1 = tcg_temp_new();
> -tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
> -(1 << MSR_RI) | (1 << MSR_EE));
> -tcg_gen_andi_tl(t1, cpu_msr,
> -~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
> -tcg_gen_or_tl(t1, t1, t0);
> -
> -gen_helper_store_msr(cpu_env, t1);
> -tcg_temp_free(t0);
> -tcg_temp_free(t1);
> -
> +mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
>  } else {
> -TCGv msr = tcg_temp_new();
> +/* mtmsr does not alter S, ME, or LE */
> +mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
>  
>  /*
>   * XXX: we need to update nip before the store if we enter
> @@ -4999,16 +5003,19 @@ static void gen_mtmsr(DisasContext *ctx)
>   *  ppc_store_msr
>   */
>  gen_update_nip(ctx, ctx->base.pc_next);
> -#if defined(TARGET_PP

Re: [PATCH v4 00/15] PPC64/TCG: Implement 'rfebb' instruction

2021-10-17 Thread David Gibson
On Sun, Oct 17, 2021 at 10:01:18PM -0300, Daniel Henrique Barboza wrote:
> This new version presents drastic design changes across all areas, most
> of them based on the feedback received in v3.
> 
> - TCG reviewers: for people looking to review only TCG related changes,
> here's a summmary of where are the TCG code in the series:
> 
> * Patches that have a lot of TCG/translation changes: 1-4, 9, 13
> * Patches that have TCG/translation bits: 6, 7, 10, 11

Patches 1..4 applied to ppc-for-6.2, still looking at the rest.

> - changes in v3:
> 
> The most drastic change is in the PMU. We're now working with an
> abstraction called PMUEvent that holds all the event information that
> the helper functions need to process it: the PMC, the event type and an
> overflow timer for cycle events. The PMU will always have 6 PMCEvent
> structs, one for each counter. Counters that aren't being used in that
> moment will have event type 'invalid'. These events are populated only
> when MMCR1 is written. Calculating the PMC values does not require
> multiple calls to 'get_PMC_event()', which has been deleted. In fact,
> this design change cut 60 lines of the power8-pmu.c file compared to the
> previous version, resulting in a more concise logic that will allow for
> easier extension of the PMU in the future.
> 
> Another change was related to PMCC bits and access control of problem
> state to PMU registers. We're now exposing both PMCC bits and doing a
> proper access control for groupA regs.
> 
> A new file was created to host the PMU translation code. The 300+ lines
> of the new power8-pmu-regs.c.inc file would be dumped into translate.c.
> 
> I've also changed the patch order. The exclusive EBB patches were pushed to
> the end of the series. I find it easier to add the placeholders for the
> PMC interrupt right at the start but populate them later on, after all
> the PMU logic has already been in place, instead of adding PMU code,
> then EBB, then go back to PMU code again.
> 
> All other changes were result of these decisions described above.
> 
> - patch 13 (former 08):
>   * renamed arg_RFEBB to arg_XL_s
>   * added Matheus' R-b
> - other patches:
>   * The changes were so substancial that the patch breakdown with the diffs
> turned out cumbersome and contraproductive.
> - v3 link: 
> https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg01250.html 
> 
> 
> Daniel Henrique Barboza (13):
>   target/ppc: add MMCR0 PMCC bits to hflags
>   target/ppc: add user read/write functions for MMCR2
>   target/ppc: adding user read/write functions for PMCs
>   target/ppc: introduce PMU events
>   target/ppc: initialize PMUEvents on MMCR1 write
>   target/ppc: PMU basic cycle count for pseries TCG
>   target/ppc: enable PMU counter overflow with cycle events
>   target/ppc: enable PMU instruction count
>   target/ppc/power8-pmu.c: add PM_RUN_INST_CMPL (0xFA) event
>   target/ppc: PMU: handle setting of PMCs while running
>   target/ppc/power8-pmu.c: handle overflow bits when PMU is running
>   PPC64/TCG: Implement 'rfebb' instruction
>   target/ppc/excp_helper.c: EBB handling adjustments
> 
> Gustavo Romero (2):
>   target/ppc: add user read/write functions for MMCR0
>   target/ppc: PMU Event-Based exception support
> 
>  hw/ppc/spapr_cpu_core.c|   6 +
>  target/ppc/cpu.h   |  89 +-
>  target/ppc/cpu_init.c  |  38 +--
>  target/ppc/excp_helper.c   |  92 ++
>  target/ppc/helper.h|   5 +
>  target/ppc/helper_regs.c   |  10 +
>  target/ppc/insn32.decode   |   5 +
>  target/ppc/meson.build |   1 +
>  target/ppc/power8-pmu-regs.c.inc   | 320 +++
>  target/ppc/power8-pmu.c| 410 +
>  target/ppc/power8-pmu.h|  25 ++
>  target/ppc/spr_tcg.h   |  12 +
>  target/ppc/translate.c |  67 
>  target/ppc/translate/branch-impl.c.inc |  33 ++
>  14 files changed, 1093 insertions(+), 20 deletions(-)
>  create mode 100644 target/ppc/power8-pmu-regs.c.inc
>  create mode 100644 target/ppc/power8-pmu.c
>  create mode 100644 target/ppc/power8-pmu.h
>  create mode 100644 target/ppc/translate/branch-impl.c.inc
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v2 04/15] bsd-user: TARGET_RESET define is unused, remove it

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  bsd-user/i386/target_arch_cpu.h   | 2 --
>  bsd-user/x86_64/target_arch_cpu.h | 2 --
>  2 files changed, 4 deletions(-)
>
> diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
> index 978e8066af..b28602adbb 100644
> --- a/bsd-user/i386/target_arch_cpu.h
> +++ b/bsd-user/i386/target_arch_cpu.h
> @@ -23,8 +23,6 @@
>
>  #define TARGET_DEFAULT_CPU_MODEL "qemu32"
>
> -#define TARGET_CPU_RESET(cpu)
> -
>  static inline void target_cpu_init(CPUX86State *env,
>  struct target_pt_regs *regs)
>  {
> diff --git a/bsd-user/x86_64/target_arch_cpu.h 
> b/bsd-user/x86_64/target_arch_cpu.h
> index 5f5ee602f9..5172b230f0 100644
> --- a/bsd-user/x86_64/target_arch_cpu.h
> +++ b/bsd-user/x86_64/target_arch_cpu.h
> @@ -23,8 +23,6 @@
>
>  #define TARGET_DEFAULT_CPU_MODEL "qemu64"
>
> -#define TARGET_CPU_RESET(cpu)
> -
>  static inline void target_cpu_init(CPUX86State *env,
>  struct target_pt_regs *regs)
>  {
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH v2 05/15] bsd-user: export get_errno and is_error from syscall.c

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> Make get_errno and is_error global so files other than syscall.c can use
> them.
>
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  bsd-user/qemu.h|  4 
>  bsd-user/syscall.c | 10 +-
>  2 files changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 522d6c4031..3b8475394c 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -235,6 +235,10 @@ extern unsigned long target_dflssiz;
>  extern unsigned long target_maxssiz;
>  extern unsigned long target_sgrowsiz;
>
> +/* syscall.c */
> +abi_long get_errno(abi_long ret);
> +bool is_error(abi_long ret);
> +
>  /* user access */
>
>  #define VERIFY_READ  PAGE_READ
> diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
> index 372836d44d..2fd2ba8330 100644
> --- a/bsd-user/syscall.c
> +++ b/bsd-user/syscall.c
> @@ -33,18 +33,18 @@
>  static abi_ulong target_brk;
>  static abi_ulong target_original_brk;
>
> -static inline abi_long get_errno(abi_long ret)
> +abi_long get_errno(abi_long ret)
>  {
> -if (ret == -1)
> +if (ret == -1) {
>  /* XXX need to translate host -> target errnos here */
>  return -(errno);
> -else
> -return ret;
> +}
> +return ret;
>  }
>
>  #define target_to_host_bitmask(x, tbl) (x)
>
> -static inline int is_error(abi_long ret)
> +bool is_error(abi_long ret)
>  {
>  return (abi_ulong)ret >= (abi_ulong)(-4096);
>  }
> --
> 2.32.0
>


Reviewed-by: Kyle Evans 



Re: [PATCH v2 07/15] bsd-user: move TARGET_MC_GET_CLEAR_RET to target_os_signal.h

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> Move TARGET_MC_GET_CLEAR_RET to freebsd/target_os_signal.h since it's
> architecture agnostic on FreeBSD.
>
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  bsd-user/freebsd/target_os_signal.h  | 3 +++
>  bsd-user/i386/target_arch_signal.h   | 2 --
>  bsd-user/x86_64/target_arch_signal.h | 2 --
>  3 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/bsd-user/freebsd/target_os_signal.h 
> b/bsd-user/freebsd/target_os_signal.h
> index 3ed454e086..1a4c5faf19 100644
> --- a/bsd-user/freebsd/target_os_signal.h
> +++ b/bsd-user/freebsd/target_os_signal.h
> @@ -1,6 +1,9 @@
>  #ifndef _TARGET_OS_SIGNAL_H_
>  #define _TARGET_OS_SIGNAL_H_
>
> +/* FreeBSD's sys/ucontext.h defines this */
> +#define TARGET_MC_GET_CLEAR_RET 0x0001
> +
>  #include "target_os_siginfo.h"
>  #include "target_arch_signal.h"
>
> diff --git a/bsd-user/i386/target_arch_signal.h 
> b/bsd-user/i386/target_arch_signal.h
> index 9812c6b034..a90750d602 100644
> --- a/bsd-user/i386/target_arch_signal.h
> +++ b/bsd-user/i386/target_arch_signal.h
> @@ -27,8 +27,6 @@
>  #define TARGET_MINSIGSTKSZ  (512 * 4)   /* min sig stack size */
>  #define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768)   /* recommended size */
>
> -#define TARGET_MC_GET_CLEAR_RET 0x0001
> -
>  struct target_sigcontext {
>  /* to be added */
>  };
> diff --git a/bsd-user/x86_64/target_arch_signal.h 
> b/bsd-user/x86_64/target_arch_signal.h
> index 4c1ff0e5ba..4bb753b08b 100644
> --- a/bsd-user/x86_64/target_arch_signal.h
> +++ b/bsd-user/x86_64/target_arch_signal.h
> @@ -27,8 +27,6 @@
>  #define TARGET_MINSIGSTKSZ  (512 * 4)   /* min sig stack size */
>  #define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768)   /* recommended size */
>
> -#define TARGET_MC_GET_CLEAR_RET 0x0001
> -
>  struct target_sigcontext {
>  /* to be added */
>  };
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH v2 08/15] bsd-user/target_os_elf.h: Remove fallback ELF_HWCAP and reorder

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> All architectures have a ELF_HWCAP, so remove the fallback ifdef.
> Place ELF_HWCAP in the same order as on native FreeBSD.
>
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  bsd-user/freebsd/target_os_elf.h | 8 ++--
>  1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/bsd-user/freebsd/target_os_elf.h 
> b/bsd-user/freebsd/target_os_elf.h
> index 2d03a883aa..adcffd1ddb 100644
> --- a/bsd-user/freebsd/target_os_elf.h
> +++ b/bsd-user/freebsd/target_os_elf.h
> @@ -38,10 +38,6 @@
>  #define ELF_PLATFORM (NULL)
>  #endif
>
> -#ifndef ELF_HWCAP
> -#define ELF_HWCAP 0
> -#endif
> -
>  /* XXX Look at the other conflicting AT_* values. */
>  #define FREEBSD_AT_NCPUS 19
>  #define FREEBSD_AT_HWCAP 25
> @@ -114,12 +110,12 @@ static abi_ulong target_create_elf_tables(abi_ulong p, 
> int argc, int envc,
>  NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
>  NEW_AUX_ENT(FREEBSD_AT_NCPUS, (abi_ulong)bsd_get_ncpu());
>  NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
> +features = ELF_HWCAP;
> +NEW_AUX_ENT(FREEBSD_AT_HWCAP, features);
>  NEW_AUX_ENT(AT_UID, (abi_ulong)getuid());
>  NEW_AUX_ENT(AT_EUID, (abi_ulong)geteuid());
>  NEW_AUX_ENT(AT_GID, (abi_ulong)getgid());
>  NEW_AUX_ENT(AT_EGID, (abi_ulong)getegid());
> -features = ELF_HWCAP;
> -NEW_AUX_ENT(FREEBSD_AT_HWCAP, features);
>  target_auxents = sp; /* Note where the aux entries are in the target 
> */
>  #ifdef ARCH_DLINFO
>  /*
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH v2 06/15] bsd-user/errno_defs.h: Add internal error numbers

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> From: Stacey Son 
>
> To emulate signals and interrupted system calls, we need to have the
> same mechanisms we have in the kernel, including these errno values.
>
> Signed-off-by: Stacey Son 
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> ---
>  bsd-user/errno_defs.h | 14 +++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h
> index 1efa502a12..b538dd93da 100644
> --- a/bsd-user/errno_defs.h
> +++ b/bsd-user/errno_defs.h
> @@ -1,6 +1,3 @@
> -/*  $OpenBSD: errno.h,v 1.20 2007/09/03 14:37:52 millert Exp $  */
> -/*  $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $   */
> -
>  /*
>   * Copyright (c) 1982, 1986, 1989, 1993
>   *  The Regents of the University of California.  All rights reserved.
> @@ -37,6 +34,9 @@
>   *  @(#)errno.h 8.5 (Berkeley) 1/21/94
>   */
>
> +#ifndef _ERRNO_DEFS_H_
> +#define _ERRNO_DEFS_H_
> +
>  #define TARGET_EPERM1   /* Operation not permitted */
>  #define TARGET_ENOENT   2   /* No such file or directory 
> */
>  #define TARGET_ESRCH3   /* No such process */
> @@ -147,3 +147,11 @@
>  #define TARGET_EIDRM89  /* Identifier removed */
>  #define TARGET_ENOMSG   90  /* No message of desired 
> type */
>  #define TARGET_ELAST90  /* Must be equal largest 
> errno */
> +
> +/* Internal errors: */
> +#define TARGET_EJUSTRETURN  254 /* Just return without
> +   modifing regs */
> +#define TARGET_ERESTART 255 /* Restart syscall */
> +#define TARGET_ERESTARTSYS  TARGET_ERESTART /* Linux compat */
> +
> +#endif /* !  _ERRNO_DEFS_H_ */
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH v2 12/15] bsd-user/sysarch: Move to using do_freebsd_arch_sysarch interface

2021-10-17 Thread Kyle Evans
On Fri, Oct 8, 2021 at 6:15 PM Warner Losh  wrote:
>
> do_freebsd_arch_sysarch() exists in $ARCH/target_arch_sysarch.h for x86.
> Call it from do_freebsd_sysarch() and remove the mostly duplicate
> version in syscall.c. Future changes will move it to os-sys.c and
> support other architectures.
>
> Signed-off-by: Warner Losh 
> Reviewed-by: Richard Henderson 
> ---
>  bsd-user/syscall.c | 45 +
>  1 file changed, 1 insertion(+), 44 deletions(-)
>
> diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
> index 2fd2ba8330..d3b9f431e2 100644
> --- a/bsd-user/syscall.c
> +++ b/bsd-user/syscall.c
> @@ -91,50 +91,7 @@ static abi_long do_obreak(abi_ulong new_brk)
>  #if defined(TARGET_I386)
>  static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms)
>  {
> -abi_long ret = 0;
> -abi_ulong val;
> -int idx;
> -
> -switch (op) {
> -#ifdef TARGET_ABI32
> -case TARGET_FREEBSD_I386_SET_GSBASE:
> -case TARGET_FREEBSD_I386_SET_FSBASE:
> -if (op == TARGET_FREEBSD_I386_SET_GSBASE)
> -#else
> -case TARGET_FREEBSD_AMD64_SET_GSBASE:
> -case TARGET_FREEBSD_AMD64_SET_FSBASE:
> -if (op == TARGET_FREEBSD_AMD64_SET_GSBASE)
> -#endif
> -idx = R_GS;
> -else
> -idx = R_FS;
> -if (get_user(val, parms, abi_ulong))
> -return -TARGET_EFAULT;
> -cpu_x86_load_seg(env, idx, 0);
> -env->segs[idx].base = val;
> -break;
> -#ifdef TARGET_ABI32
> -case TARGET_FREEBSD_I386_GET_GSBASE:
> -case TARGET_FREEBSD_I386_GET_FSBASE:
> -if (op == TARGET_FREEBSD_I386_GET_GSBASE)
> -#else
> -case TARGET_FREEBSD_AMD64_GET_GSBASE:
> -case TARGET_FREEBSD_AMD64_GET_FSBASE:
> -if (op == TARGET_FREEBSD_AMD64_GET_GSBASE)
> -#endif
> -idx = R_GS;
> -else
> -idx = R_FS;
> -val = env->segs[idx].base;
> -if (put_user(val, parms, abi_ulong))
> -return -TARGET_EFAULT;
> -break;
> -/* XXX handle the others... */
> -default:
> -ret = -TARGET_EINVAL;
> -break;
> -}
> -return ret;
> +do_freebsd_arch_sysarch(env, op, parms);
>  }
>  #endif
>
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



  1   2   >