[PATCH] target/ppc: Improve logging in Radix MMU

2021-12-21 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 target/ppc/mmu-radix64.c | 55 +---
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 5b0e62e676dc..abfa13f303bb 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -97,12 +97,22 @@ static void ppc_radix64_raise_segi(PowerPCCPU *cpu, 
MMUAccessType access_type,
 env->error_code = 0;
 }
 
+static inline const char *access_str(MMUAccessType access_type)
+{
+return access_type == MMU_DATA_LOAD ? "reading" :
+(access_type == MMU_DATA_STORE ? "writing" : "execute");
+}
+
 static void ppc_radix64_raise_si(PowerPCCPU *cpu, MMUAccessType access_type,
  vaddr eaddr, uint32_t cause)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" cause %08x\n",
+  __func__, access_str(access_type),
+  eaddr, cause);
+
 switch (access_type) {
 case MMU_INST_FETCH:
 /* Instruction Storage Interrupt */
@@ -130,6 +140,11 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, 
MMUAccessType access_type,
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" 0x%"
+  HWADDR_PRIx" cause %08x\n",
+  __func__, access_str(access_type),
+  eaddr, g_raddr, cause);
+
 switch (access_type) {
 case MMU_INST_FETCH:
 /* H Instruction Storage Interrupt */
@@ -306,6 +321,15 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU 
*cpu,
 hwaddr pte_addr;
 uint64_t pte;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u (prot %c%c%c) 0x%"HWADDR_PRIx"\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx,
+  *h_prot & PAGE_READ ? 'r' : '-',
+  *h_prot & PAGE_WRITE ? 'w' : '-',
+  *h_prot & PAGE_EXEC ? 'x' : '-',
+  g_raddr);
+
 *h_page_size = PRTBE_R_GET_RTS(pate.dw0);
 /* No valid pte or access denied due to protection */
 if (ppc_radix64_walk_tree(CPU(cpu)->as, g_raddr, pate.dw0 & PRTBE_R_RPDB,
@@ -343,6 +367,11 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU 
*cpu,
 hwaddr h_raddr, pte_addr;
 int ret;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u pid %ld\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx, pid);
+
 /* Index Process Table by PID to Find Corresponding Process Table Entry */
 offset = pid * sizeof(struct prtb_entry);
 size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
@@ -468,9 +497,10 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU 
*cpu,
  *  | = On| Process Scoped |Scoped |
  *  +-++---+
  */
-bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
-   hwaddr *raddr, int *psizep, int *protp, int mmu_idx,
-   bool guest_visible)
+static bool __ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr,
+MMUAccessType access_type, hwaddr *raddr,
+int *psizep, int *protp, int mmu_idx,
+bool guest_visible)
 {
 CPUPPCState *env = >env;
 uint64_t lpid, pid;
@@ -588,3 +618,22 @@ bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, 
MMUAccessType access_type,
 
 return true;
 }
+
+bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
+   hwaddr *raddrp, int *psizep, int *protp, int mmu_idx,
+   bool guest_visible)
+{
+bool ret = __ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
+   psizep, protp, mmu_idx, guest_visible);
+
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u (prot %c%c%c) -> 0x%"HWADDR_PRIx"\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx,
+  *protp & PAGE_READ ? 'r' : '-',
+  *protp & PAGE_WRITE ? 'w' : '-',
+  *protp & PAGE_EXEC ? 'x' : '-',
+  *raddrp);
+
+return ret;
+}
-- 
2.31.1




Re: [PATCH] tests/qtest/virtio-net-failover: Use g_random_int() instead of g_test_rand_int()

2021-12-21 Thread Thomas Huth

On 21/12/2021 20.32, Richard Henderson wrote:

On 12/21/21 2:32 AM, Thomas Huth wrote:
Using g_file_open_tmp is certainly better ... but the tests are currently 
written in a way where they require the file name of the temporary file - 
so switching to g_file_open_tmp() (which only provides a file handle) 
certainly would need some rewrite here...


Incorrect.  g_file_open_tmp returns the open file handle, but also returns 
the filename in *name_used.


D'oh - not sure how I missed that yesterday :-/

I should think you can close the file handle straight away and use the 
filename.


Ok, then let's continue with that approach.

 Thomas




Re: [PATCH 2/2] qapi/block: Restrict vhost-user-blk to CONFIG_VHOST_USER_BLK_SERVER

2021-12-21 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> Do not list vhost-user-blk in BlockExportType
> when CONFIG_VHOST_USER_BLK_SERVER is disabled.
>
> Fixes: 90fc91d50b7 ("convert vhost-user-blk server to block export API")

My immediate reaction was "what exactly is broken before this patch?"

I think it's introspection: query-qmp-schema has vhost-user-blk even
though it's not actually available.  Let's spell that out.

> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  qapi/block-export.json | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/block-export.json b/qapi/block-export.json
> index c1b92ce1c1c..6bc29a75dc0 100644
> --- a/qapi/block-export.json
> +++ b/qapi/block-export.json
> @@ -277,7 +277,8 @@
>  # Since: 4.2
>  ##
>  { 'enum': 'BlockExportType',
> -  'data': [ 'nbd', 'vhost-user-blk',
> +  'data': [ 'nbd',
> +{ 'name': 'vhost-user-blk', 'if': 'CONFIG_VHOST_USER_BLK_SERVER' 
> },
>  { 'name': 'fuse', 'if': 'CONFIG_FUSE' } ] }
>  
>  ##

Doesn't compile when I configure --disable-vhost-user.  Fix:

diff --git a/qapi/block-export.json b/qapi/block-export.json
index 6bc29a75dc..f9ce79a974 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -320,7 +320,8 @@
   'discriminator': 'type',
   'data': {
   'nbd': 'BlockExportOptionsNbd',
-  'vhost-user-blk': 'BlockExportOptionsVhostUserBlk',
+  'vhost-user-blk': { 'type': 'BlockExportOptionsVhostUserBlk',
+  'if': 'CONFIG_VHOST_USER_BLK_SERVER' },
   'fuse': { 'type': 'BlockExportOptionsFuse',
 'if': 'CONFIG_FUSE' }
} }




Re: [RFC v2 04/12] target/ppc: powerpc_excp: Stop passing excp_model around

2021-12-21 Thread Cédric Le Goater

On 12/20/21 19:18, Fabiano Rosas wrote:

We can just access it directly in powerpc_excp.

Signed-off-by: Fabiano Rosas 



Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  target/ppc/excp_helper.c | 43 
  1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 7bdc1e8410..45641f6d1d 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -293,10 +293,11 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
   * Note that this function should be greatly optimized when called
   * with a constant excp, from ppc_hw_interrupt
   */
-static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
+static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
  {
  CPUState *cs = CPU(cpu);
  CPUPPCState *env = >env;
+int excp_model = env->excp_model;
  target_ulong msr, new_msr, vector;
  int srr0, srr1, lev = -1;
  
@@ -878,9 +879,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)

  void ppc_cpu_do_interrupt(CPUState *cs)
  {
  PowerPCCPU *cpu = POWERPC_CPU(cs);
-CPUPPCState *env = >env;
  
-powerpc_excp(cpu, env->excp_model, cs->exception_index);

+powerpc_excp(cpu, cs->exception_index);
  }
  
  static void ppc_hw_interrupt(CPUPPCState *env)

@@ -891,20 +891,20 @@ static void ppc_hw_interrupt(CPUPPCState *env)
  /* External reset */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
+powerpc_excp(cpu, POWERPC_EXCP_RESET);
  return;
  }
  /* Machine check exception */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
+powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
  return;
  }
  #if 0 /* TODO */
  /* External debug exception */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);
+powerpc_excp(cpu, POWERPC_EXCP_DEBUG);
  return;
  }
  #endif
@@ -924,7 +924,7 @@ static void ppc_hw_interrupt(CPUPPCState *env)
  if ((async_deliver || msr_hv == 0) && hdice) {
  /* HDEC clears on delivery */
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
+powerpc_excp(cpu, POWERPC_EXCP_HDECR);
  return;
  }
  }
@@ -934,7 +934,7 @@ static void ppc_hw_interrupt(CPUPPCState *env)
  /* LPCR will be clear when not supported so this will work */
  bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
  if ((async_deliver || msr_hv == 0) && hvice) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT);
+powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
  return;
  }
  }
@@ -946,14 +946,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)
  /* HEIC blocks delivery to the hypervisor */
  if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
  (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
+powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
  return;
  }
  }
  if (msr_ce != 0) {
  /* External critical interrupt */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);
+powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
  return;
  }
  }
@@ -961,24 +961,24 @@ static void ppc_hw_interrupt(CPUPPCState *env)
  /* Watchdog timer on embedded PowerPC */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);
+powerpc_excp(cpu, POWERPC_EXCP_WDT);
  return;
  }
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);
+powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
  return;
  }
  /* Fixed interval timer on embedded PowerPC */
  if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);
+powerpc_excp(cpu, POWERPC_EXCP_FIT);
  return;
  }
  /* 

Re: [RFC v2 03/12] target/ppc: powerpc_excp: Move system call vectored code together

2021-12-21 Thread Cédric Le Goater

Adding Nicholas.

On 12/20/21 19:18, Fabiano Rosas wrote:

Now that 'vector' is known before calling the interrupt-specific setup
code, we can move all of the scv setup into one place.

No functional change intended.

Signed-off-by: Fabiano Rosas 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  target/ppc/excp_helper.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 14fd0213a0..7bdc1e8410 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -549,6 +549,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  env->nip += 4;
  new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
  new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+
+vector += lev * 0x20;
+
+env->lr = env->nip;
+env->ctr = msr;
  break;
  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
*/
  case POWERPC_EXCP_APU:   /* Auxiliary processor unavailable  
*/
@@ -862,14 +867,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  
  /* Save MSR */

  env->spr[srr1] = msr;
-
-#if defined(TARGET_PPC64)
-} else {
-vector += lev * 0x20;
-
-env->lr = env->nip;
-env->ctr = msr;
-#endif
  }
  
  /* This can update new_msr and vector if AIL applies */







Re: [RFC v2 01/12] target/ppc: powerpc_excp: Set alternate SRRs directly

2021-12-21 Thread Cédric Le Goater

On 12/20/21 19:18, Fabiano Rosas wrote:

There are currently only two interrupts that use alternate SRRs, so
let them write to them directly during the setup code.

No functional change intented.


intended.



Signed-off-by: Fabiano Rosas 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  target/ppc/excp_helper.c | 23 ---
  1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index f90e616aac..8b9c6bc5a8 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -298,7 +298,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  CPUState *cs = CPU(cpu);
  CPUPPCState *env = >env;
  target_ulong msr, new_msr, vector;
-int srr0, srr1, asrr0, asrr1, lev = -1;
+int srr0, srr1, lev = -1;
  
  qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx

" => %08x (%02x)\n", env->nip, excp, env->error_code);
@@ -319,8 +319,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  /* target registers */
  srr0 = SPR_SRR0;
  srr1 = SPR_SRR1;
-asrr0 = -1;
-asrr1 = -1;
  
  /*

   * check for special resume at 0x100 from doze/nap/sleep/winkle on
@@ -410,8 +408,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  /* FIXME: choose one or the other based on CPU type */
  srr0 = SPR_BOOKE_MCSRR0;
  srr1 = SPR_BOOKE_MCSRR1;
-asrr0 = SPR_BOOKE_CSRR0;
-asrr1 = SPR_BOOKE_CSRR1;
+
+env->spr[SPR_BOOKE_CSRR0] = env->nip;
+env->spr[SPR_BOOKE_CSRR1] = msr;
  break;
  default:
  break;
@@ -570,8 +569,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  /* FIXME: choose one or the other based on CPU type */
  srr0 = SPR_BOOKE_DSRR0;
  srr1 = SPR_BOOKE_DSRR1;
-asrr0 = SPR_BOOKE_CSRR0;
-asrr1 = SPR_BOOKE_CSRR1;
+
+env->spr[SPR_BOOKE_CSRR0] = env->nip;
+env->spr[SPR_BOOKE_CSRR1] = msr;
+
  /* DBSR already modified by caller */
  } else {
  cpu_abort(cs, "Debug exception triggered on unsupported model\n");
@@ -838,14 +839,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  
  vector |= env->excp_prefix;
  
-/* If any alternate SRR register are defined, duplicate saved values */

-if (asrr0 != -1) {
-env->spr[asrr0] = env->nip;
-}
-if (asrr1 != -1) {
-env->spr[asrr1] = msr;
-}
-
  #if defined(TARGET_PPC64)
  if (excp_model == POWERPC_EXCP_BOOKE) {
  if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {






Re: [RFC v2 02/12] target/ppc: powerpc_excp: Set vector earlier

2021-12-21 Thread Cédric Le Goater

Adding Nicholas.

On 12/20/21 19:18, Fabiano Rosas wrote:

None of the interrupt setup code touches 'vector', so we can move it
earlier in the function. This will allow us to later move the System
Call Vectored setup that is on the top level into the
POWERPC_EXCP_SYSCALL_VECTORED code block.

This patch also moves the verification for when 'excp' does not have
an address associated with it. We now bail a little earlier when that
is the case. This should not cause any visible effects.

Signed-off-by: Fabiano Rosas 



Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  target/ppc/excp_helper.c | 16 
  1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 8b9c6bc5a8..14fd0213a0 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -352,6 +352,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  }
  #endif
  
+vector = env->excp_vectors[excp];

+if (vector == (target_ulong)-1ULL) {
+cpu_abort(cs, "Raised an exception without defined vector %d\n",
+  excp);
+}
+
+vector |= env->excp_prefix;
+
  switch (excp) {
  case POWERPC_EXCP_NONE:
  /* Should never happen */
@@ -831,14 +839,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
  }
  #endif
  
-vector = env->excp_vectors[excp];

-if (vector == (target_ulong)-1ULL) {
-cpu_abort(cs, "Raised an exception without defined vector %d\n",
-  excp);
-}
-
-vector |= env->excp_prefix;
-
  #if defined(TARGET_PPC64)
  if (excp_model == POWERPC_EXCP_BOOKE) {
  if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {






Re: [PATCH 1/4] dma: Let st*_dma() take MemTxAttrs argument

2021-12-21 Thread Cédric Le Goater

On 12/18/21 15:51, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling st*_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  include/hw/pci/pci.h   |  3 ++-
  include/hw/ppc/spapr_vio.h | 12 
  include/sysemu/dma.h   | 10 ++
  hw/nvram/fw_cfg.c  |  4 ++--
  4 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index a751ab5a75d..d07e9707b48 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -859,7 +859,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, 
dma_addr_t addr,
  static inline void st##_s##_pci_dma(PCIDevice *dev, \
  dma_addr_t addr, uint##_bits##_t val) 
\
  {   \
-st##_s##_dma(pci_get_address_space(dev), addr, val);\
+st##_s##_dma(pci_get_address_space(dev), addr, val, \
+ MEMTXATTRS_UNSPECIFIED); \
  }
  
  PCI_DMA_DEFINE_LDST(ub, b, 8);

diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 5d2ea8e6656..e87f8e6f596 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -118,10 +118,14 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, 
uint64_t taddr,
  H_DEST_PARM : H_SUCCESS;
  }
  
-#define vio_stb(_dev, _addr, _val) (stb_dma(&(_dev)->as, (_addr), (_val)))

-#define vio_sth(_dev, _addr, _val) (stw_be_dma(&(_dev)->as, (_addr), (_val)))
-#define vio_stl(_dev, _addr, _val) (stl_be_dma(&(_dev)->as, (_addr), (_val)))
-#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val)))
+#define vio_stb(_dev, _addr, _val) \
+(stb_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_sth(_dev, _addr, _val) \
+(stw_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_stl(_dev, _addr, _val) \
+(stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_stq(_dev, _addr, _val) \
+(stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
  #define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
  
  int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);

diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 9f998edbea4..2a60d2c5d61 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -250,10 +250,11 @@ static inline void dma_memory_unmap(AddressSpace *as,
  }   \
  static inline void st##_sname##_##_end##_dma(AddressSpace *as,  \
   dma_addr_t addr,   \
- uint##_bits##_t val)   \
+ uint##_bits##_t val,   \
+ MemTxAttrs attrs)  \
  {   \
  val = cpu_to_##_end##_bits(val);\
-dma_memory_write(as, addr, , (_bits) / 8, MEMTXATTRS_UNSPECIFIED); 
\
+dma_memory_write(as, addr, , (_bits) / 8, attrs); \
  }
  
  static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)

@@ -264,9 +265,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, 
dma_addr_t addr)
  return val;
  }
  
-static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val)

+static inline void stb_dma(AddressSpace *as, dma_addr_t addr,
+   uint8_t val, MemTxAttrs attrs)
  {
-dma_memory_write(as, addr, , 1, MEMTXATTRS_UNSPECIFIED);
+dma_memory_write(as, addr, , 1, attrs);
  }
  
  DEFINE_LDST_DMA(uw, w, 16, le);

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 9b91b15cb08..e5f3c981841 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -360,7 +360,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
  if (dma_memory_read(s->dma_as, dma_addr,
  , sizeof(dma), MEMTXATTRS_UNSPECIFIED)) {
  stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
-   FW_CFG_DMA_CTL_ERROR);
+   FW_CFG_DMA_CTL_ERROR, MEMTXATTRS_UNSPECIFIED);
  return;
  }
  
@@ -446,7 +446,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s)

  }
  
  stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),

-dma.control);
+dma.control, MEMTXATTRS_UNSPECIFIED);
  
  trace_fw_cfg_read(s, 0);

  }






[PATCH 5/8] ppc/ppc405: Rework ppc_40x_timers_init() to use a PowerPCCPU

2021-12-21 Thread Cédric Le Goater
This is a small cleanup to ease reading.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc.c | 42 +++---
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index cca99cb86f81..bb5bee9a3382 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1124,14 +1124,12 @@ struct ppc40x_timer_t {
 /* Fixed interval timer */
 static void cpu_4xx_fit_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 uint64_t now, next;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1193,13 +1191,11 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t 
*tb_env, int is_excp)
 
 static void cpu_4xx_pit_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 env->spr[SPR_40x_TSR] |= 1 << 27;
@@ -1216,14 +1212,12 @@ static void cpu_4xx_pit_cb (void *opaque)
 /* Watchdog timer */
 static void cpu_4xx_wdt_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 uint64_t now, next;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1341,24 +1335,26 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, 
uint32_t freq,
 {
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
+PowerPCCPU *cpu = env_archcpu(env);
+
+trace_ppc40x_timers_init(freq);
 
 tb_env = g_malloc0(sizeof(ppc_tb_t));
+ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
+
 env->tb_env = tb_env;
 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
-ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
 tb_env->tb_freq = freq;
 tb_env->decr_freq = freq;
 tb_env->opaque = ppc40x_timer;
-trace_ppc40x_timers_init(freq);
-if (ppc40x_timer != NULL) {
-/* We use decr timer for PIT */
-tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_pit_cb, 
env);
-ppc40x_timer->fit_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_fit_cb, env);
-ppc40x_timer->wdt_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_wdt_cb, env);
-ppc40x_timer->decr_excp = decr_excp;
-}
+
+/* We use decr timer for PIT */
+tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_pit_cb, 
cpu);
+ppc40x_timer->fit_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_fit_cb, cpu);
+ppc40x_timer->wdt_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_wdt_cb, cpu);
+ppc40x_timer->decr_excp = decr_excp;
 
 return _40x_set_tb_clk;
 }
-- 
2.31.1




[PATCH 7/8] ppc/ppc405: Introduce a store helper for SPR_40x_PID

2021-12-21 Thread Cédric Le Goater
The PID SPR of the 405 CPU contains the translation ID of the TLB
which is a 8-bit field. Enforce the mask with a store helper.

Cc: Christophe Leroy 
Signed-off-by: Cédric Le Goater 
---
 target/ppc/spr_tcg.h   | 1 +
 target/ppc/cpu_init.c  | 2 +-
 target/ppc/translate.c | 8 
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index 64cf5302cb86..89ff111724dc 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -89,6 +89,7 @@ void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int 
gprn);
 void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn);
+void spr_write_40x_pid(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn);
 void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn);
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index b5e2fde9ec4d..9ef9a1a5ddd5 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -1454,7 +1454,7 @@ static void register_405_sprs(CPUPPCState *env)
 /* MMU */
 spr_register(env, SPR_40x_PID, "PID",
  SPR_NOACCESS, SPR_NOACCESS,
- _read_generic, _write_generic,
+ _read_generic, _write_40x_pid,
  0x);
 spr_register(env, SPR_4xx_CCR0, "CCR0",
  SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index eb45f679d34f..cb8ab4d67635 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -890,6 +890,14 @@ void spr_write_40x_tsr(DisasContext *ctx, int sprn, int 
gprn)
 gen_helper_store_40x_tsr(cpu_env, cpu_gpr[gprn]);
 }
 
+void spr_write_40x_pid(DisasContext *ctx, int sprn, int gprn)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xFF);
+gen_store_spr(SPR_40x_PID, t0);
+tcg_temp_free(t0);
+}
+
 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
 {
 gen_icount_io_start(ctx);
-- 
2.31.1




[PATCH 1/8] target/ppc: Print out literal exception names in logs

2021-12-21 Thread Cédric Le Goater
It facilitates reading the logs when mask CPU_LOG_INT is activated. We
should do the same for error codes.

Cc: Fabiano Rosas 
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 75 +++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index f90e616aacda..71ad983e67d6 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -32,6 +32,78 @@
 
 /* #define DEBUG_SOFTWARE_TLB */
 
+static inline const char *powerpc_excp_name(int excp)
+{
+switch (excp) {
+case POWERPC_EXCP_CRITICAL: return "CRITICAL";
+case POWERPC_EXCP_MCHECK:   return "MCHECK";
+case POWERPC_EXCP_DSI:  return "DSI";
+case POWERPC_EXCP_ISI:  return "ISI";
+case POWERPC_EXCP_EXTERNAL: return "EXTERNAL";
+case POWERPC_EXCP_ALIGN:return "ALIGN";
+case POWERPC_EXCP_PROGRAM:  return "PROGRAM";
+case POWERPC_EXCP_FPU:  return "FPU";
+case POWERPC_EXCP_SYSCALL:  return "SYSCALL";
+case POWERPC_EXCP_APU:  return "APU";
+case POWERPC_EXCP_DECR: return "DECR";
+case POWERPC_EXCP_FIT:  return "FIT";
+case POWERPC_EXCP_WDT:  return "WDT";
+case POWERPC_EXCP_DTLB: return "DTLB";
+case POWERPC_EXCP_ITLB: return "ITLB";
+case POWERPC_EXCP_DEBUG:return "DEBUG";
+case POWERPC_EXCP_SPEU: return "SPEU";
+case POWERPC_EXCP_EFPDI:return "EFPDI";
+case POWERPC_EXCP_EFPRI:return "EFPRI";
+case POWERPC_EXCP_EPERFM:   return "EPERFM";
+case POWERPC_EXCP_DOORI:return "DOORI";
+case POWERPC_EXCP_DOORCI:   return "DOORCI";
+case POWERPC_EXCP_GDOORI:   return "GDOORI";
+case POWERPC_EXCP_GDOORCI:  return "GDOORCI";
+case POWERPC_EXCP_HYPPRIV:  return "HYPPRIV";
+case POWERPC_EXCP_RESET:return "RESET";
+case POWERPC_EXCP_DSEG: return "DSEG";
+case POWERPC_EXCP_ISEG: return "ISEG";
+case POWERPC_EXCP_HDECR:return "HDECR";
+case POWERPC_EXCP_TRACE:return "TRACE";
+case POWERPC_EXCP_HDSI: return "HDSI";
+case POWERPC_EXCP_HISI: return "HISI";
+case POWERPC_EXCP_HDSEG:return "HDSEG";
+case POWERPC_EXCP_HISEG:return "HISEG";
+case POWERPC_EXCP_VPU:  return "VPU";
+case POWERPC_EXCP_PIT:  return "PIT";
+case POWERPC_EXCP_IO:   return "IO";
+case POWERPC_EXCP_RUNM: return "RUNM";
+case POWERPC_EXCP_EMUL: return "EMUL";
+case POWERPC_EXCP_IFTLB:return "IFTLB";
+case POWERPC_EXCP_DLTLB:return "DLTLB";
+case POWERPC_EXCP_DSTLB:return "DSTLB";
+case POWERPC_EXCP_FPA:  return "FPA";
+case POWERPC_EXCP_DABR: return "DABR";
+case POWERPC_EXCP_IABR: return "IABR";
+case POWERPC_EXCP_SMI:  return "SMI";
+case POWERPC_EXCP_PERFM:return "PERFM";
+case POWERPC_EXCP_THERM:return "THERM";
+case POWERPC_EXCP_VPUA: return "VPUA";
+case POWERPC_EXCP_SOFTP:return "SOFTP";
+case POWERPC_EXCP_MAINT:return "MAINT";
+case POWERPC_EXCP_MEXTBR:   return "MEXTBR";
+case POWERPC_EXCP_NMEXTBR:  return "NMEXTBR";
+case POWERPC_EXCP_ITLBE:return "ITLBE";
+case POWERPC_EXCP_DTLBE:return "DTLBE";
+case POWERPC_EXCP_VSXU: return "VSXU";
+case POWERPC_EXCP_FU:   return "FU";
+case POWERPC_EXCP_HV_EMU:   return "HV_EMU";
+case POWERPC_EXCP_HV_MAINT: return "HV_MAINT";
+case POWERPC_EXCP_HV_FU:return "HV_FU";
+case POWERPC_EXCP_SDOOR:return "SDOOR";
+case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
+case POWERPC_EXCP_HVIRT:return "HVIRT";
+case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
+default:
+g_assert_not_reached();
+}
+}
+
 /*/
 /* Exception processing */
 #if !defined(CONFIG_USER_ONLY)
@@ -301,7 +373,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 int srr0, srr1, asrr0, asrr1, lev = -1;
 
 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
-  " => %08x (%02x)\n", env->nip, excp, env->error_code);
+  " => %s (%d) error=%02x\n", env->nip, 
powerpc_excp_name(excp),
+  excp, env->error_code);
 
 /* new srr1 value excluding must-be-zero bits */
 if (excp_model == POWERPC_EXCP_BOOKE) {
-- 
2.31.1




Re: [PATCH 3/4] dma: Let st*_dma() propagate MemTxResult

2021-12-21 Thread Cédric Le Goater

On 12/18/21 15:51, Philippe Mathieu-Daudé wrote:

dma_memory_write() returns a MemTxResult type. Do not discard
it, return it to the caller.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/sysemu/dma.h | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index b711d390a4f..191cf0b271a 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -249,13 +249,13 @@ static inline void dma_memory_unmap(AddressSpace *as,
  dma_memory_read(as, addr, , (_bits) / 8, attrs); \
  return _end##_bits##_to_cpu(val);   \
  }   \
-static inline void st##_sname##_##_end##_dma(AddressSpace *as,  \
- dma_addr_t addr,   \
- uint##_bits##_t val,   \
- MemTxAttrs attrs)  \
-{   \
-val = cpu_to_##_end##_bits(val);\
-dma_memory_write(as, addr, , (_bits) / 8, attrs);   \
+static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
+dma_addr_t addr, \
+uint##_bits##_t val, \
+MemTxAttrs attrs) \
+{ \
+val = cpu_to_##_end##_bits(val); \
+return dma_memory_write(as, addr, , (_bits) / 8, attrs); \
  }
  
  static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs)

@@ -266,10 +266,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, 
dma_addr_t addr, MemTxAttrs att
  return val;
  }
  
-static inline void stb_dma(AddressSpace *as, dma_addr_t addr,

-   uint8_t val, MemTxAttrs attrs)
+static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,
+  uint8_t val, MemTxAttrs attrs)
  {
-dma_memory_write(as, addr, , 1, attrs);
+return dma_memory_write(as, addr, , 1, attrs);
  }
  
  DEFINE_LDST_DMA(uw, w, 16, le);







Re: [PATCH 4/4] dma: Let ld*_dma() propagate MemTxResult

2021-12-21 Thread Cédric Le Goater

On 12/18/21 15:51, Philippe Mathieu-Daudé wrote:

dma_memory_read() returns a MemTxResult type. Do not discard
it, return it to the caller.


Good ! We should be using it in XIVE.


Update the few callers.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/hw/pci/pci.h   |  6 --
  include/hw/ppc/spapr_vio.h |  6 +-
  include/sysemu/dma.h   | 25 -
  hw/intc/pnv_xive.c |  8 
  hw/usb/hcd-xhci.c  |  7 ---
  5 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 0613308b1b6..8c5f2ed5054 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -854,8 +854,10 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, 
dma_addr_t addr,
  static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev,  \
 dma_addr_t addr) \
  {   \
-return ld##_l##_dma(pci_get_address_space(dev), addr,   \
-MEMTXATTRS_UNSPECIFIED);\
+uint##_bits##_t val; \
+ld##_l##_dma(pci_get_address_space(dev), addr, , \
+ MEMTXATTRS_UNSPECIFIED); \
+return val; \
  }   \
  static inline void st##_s##_pci_dma(PCIDevice *dev, \
  dma_addr_t addr, uint##_bits##_t val) 
\
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index d2ec9b0637f..7eae1a48478 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -127,7 +127,11 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, 
uint64_t taddr,
  #define vio_stq(_dev, _addr, _val) \
  (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
  #define vio_ldq(_dev, _addr) \
-(ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED))
+({ \
+uint64_t _val; \
+ldq_be_dma(&(_dev)->as, (_addr), &_val, MEMTXATTRS_UNSPECIFIED); \
+_val; \
+})
  
  int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
  
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h

index 191cf0b271a..589f5ba52a2 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -241,14 +241,15 @@ static inline void dma_memory_unmap(AddressSpace *as,
  }
  
  #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \

-static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \
-dma_addr_t addr, \
-MemTxAttrs attrs) \
-{   \
-uint##_bits##_t val;\
-dma_memory_read(as, addr, , (_bits) / 8, attrs); \
-return _end##_bits##_to_cpu(val);   \
-}   \
+static inline MemTxResult ld##_lname##_##_end##_dma(AddressSpace *as, \
+dma_addr_t addr, \
+uint##_bits##_t *pval, 
\
+MemTxAttrs attrs) \
+{ \
+MemTxResult res = dma_memory_read(as, addr, pval, (_bits) / 8, attrs); 
\
+_end##_bits##_to_cpus(pval); \
+return res; \
+} \
  static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
  dma_addr_t addr, \
  uint##_bits##_t val, \
@@ -258,12 +259,10 @@ static inline void dma_memory_unmap(AddressSpace *as,
  return dma_memory_write(as, addr, , (_bits) / 8, attrs); \
  }
  
-static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs)

+static inline MemTxResult ldub_dma(AddressSpace *as, dma_addr_t addr,
+   uint8_t *val, MemTxAttrs attrs)
  {
-uint8_t val;
-
-dma_memory_read(as, addr, , 1, attrs);
-return val;
+return dma_memory_read(as, addr, val, 1, attrs);
  }
  
  static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index d9249bbc0c1..bb207514f2d 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
uint32_t type,
  
  /* Get the page size of the indirect table. */

  vsd_addr = vsd & VSD_ADDRESS_MASK;
-vsd = ldq_be_dma(_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
+ldq_be_dma(_space_memory, vsd_addr, , MEMTXATTRS_UNSPECIFIED);
  
   

[PATCH 4/8] ppc/ppc405: Restore TCR and STR write handlers

2021-12-21 Thread Cédric Le Goater
The 405 timers were broken when booke support was added. Assumption
was made that the register numbers were the same but it's not :

SPR_BOOKE_TSR (0x150)
SPR_BOOKE_TCR (0x154)
SPR_40x_TSR   (0x3D8)
SPR_40x_TCR   (0x3DA)

Cc: Christophe Leroy 
Fixes: ddd1055b07fd ("PPC: booke timers")
Signed-off-by: Cédric Le Goater 
---
 target/ppc/cpu.h |  2 ++
 target/ppc/helper.h  |  2 ++
 target/ppc/spr_tcg.h |  2 ++
 hw/ppc/ppc.c | 25 +
 target/ppc/cpu_init.c|  4 ++--
 target/ppc/timebase_helper.c | 10 ++
 target/ppc/translate.c   | 12 
 hw/ppc/trace-events  |  2 ++
 8 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc66c3561dab..4808e10ebe8b 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1399,6 +1399,8 @@ target_ulong load_40x_pit(CPUPPCState *env);
 void store_40x_pit(CPUPPCState *env, target_ulong val);
 void store_40x_dbcr0(CPUPPCState *env, uint32_t val);
 void store_40x_sler(CPUPPCState *env, uint32_t val);
+void store_40x_tcr(CPUPPCState *env, target_ulong val);
+void store_40x_tsr(CPUPPCState *env, target_ulong val);
 void store_booke_tcr(CPUPPCState *env, target_ulong val);
 void store_booke_tsr(CPUPPCState *env, target_ulong val);
 void ppc_tlb_invalidate_all(CPUPPCState *env);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fb6cac38b4c5..f9c72dcd504d 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -706,6 +706,8 @@ DEF_HELPER_2(store_hid0_601, void, env, tl)
 DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
 DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_2(store_40x_pit, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_40x_tcr, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_40x_tsr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(store_40x_dbcr0, void, env, tl)
 DEF_HELPER_2(store_40x_sler, void, env, tl)
 DEF_HELPER_FLAGS_2(store_booke_tcr, TCG_CALL_NO_RWG, void, env, tl)
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index f98d97c0ba17..64cf5302cb86 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -87,6 +87,8 @@ void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn);
 void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn);
+void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn);
+void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn);
 void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn);
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 818d75798584..cca99cb86f81 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1300,6 +1300,31 @@ target_ulong load_40x_pit (CPUPPCState *env)
 return cpu_ppc_load_decr(env);
 }
 
+void store_40x_tsr(CPUPPCState *env, target_ulong val)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+
+trace_ppc40x_store_tcr(val);
+
+env->spr[SPR_40x_TSR] &= ~(val & 0xFC00);
+if (val & 0x8000) {
+ppc_set_irq(cpu, PPC_INTERRUPT_PIT, 0);
+}
+}
+
+void store_40x_tcr(CPUPPCState *env, target_ulong val)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+ppc_tb_t *tb_env;
+
+trace_ppc40x_store_tsr(val);
+
+tb_env = env->tb_env;
+env->spr[SPR_40x_TCR] = val & 0xFFC0;
+start_stop_pit(env, tb_env, 1);
+cpu_4xx_wdt_cb(cpu);
+}
+
 static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
 {
 CPUPPCState *env = opaque;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 06ef15cd9e4e..b5e2fde9ec4d 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -1440,11 +1440,11 @@ static void register_40x_sprs(CPUPPCState *env)
  0x);
 spr_register(env, SPR_40x_TCR, "TCR",
  SPR_NOACCESS, SPR_NOACCESS,
- _read_generic, _write_booke_tcr,
+ _read_generic, _write_40x_tcr,
  0x);
 spr_register(env, SPR_40x_TSR, "TSR",
  SPR_NOACCESS, SPR_NOACCESS,
- _read_generic, _write_booke_tsr,
+ _read_generic, _write_40x_tsr,
  0x);
 }
 
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 8ff4080eb91e..af378318c19c 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -144,6 +144,16 @@ void helper_store_40x_pit(CPUPPCState *env, target_ulong 
val)
 store_40x_pit(env, val);
 }
 
+void helper_store_40x_tcr(CPUPPCState *env, target_ulong val)
+{
+store_40x_tcr(env, val);
+}
+
+void helper_store_40x_tsr(CPUPPCState *env, target_ulong val)
+{
+store_40x_tsr(env, val);
+}
+
 void 

[PATCH 8/8] ppc/ppc405: Dump specific registers

2021-12-21 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 target/ppc/cpu_init.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 9ef9a1a5ddd5..8f6a58e82483 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -8689,6 +8689,17 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
  * they can be read with "p $ivor0", "p $ivor1", etc.
  */
 }
+if (env->excp_model == POWERPC_EXCP_40x) {
+qemu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
+ "ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
+ env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
+ env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
+
+qemu_fprintf(f, " EVPR " TARGET_FMT_lx "  SRR2 " TARGET_FMT_lx
+ "   SRR3 " TARGET_FMT_lx  "   PID " TARGET_FMT_lx "\n",
+ env->spr[SPR_40x_EVPR], env->spr[SPR_40x_SRR2],
+ env->spr[SPR_40x_SRR3], env->spr[SPR_40x_PID]);
+}
 
 #if defined(TARGET_PPC64)
 if (env->flags & POWERPC_FLAG_CFAR) {
-- 
2.31.1




[PATCH] intel-iommu: correctly check passthrough during translation

2021-12-21 Thread Jason Wang
When scsalable mode is enabled, the passthrough more is not determined
by the context entry but PASID entry, so switch to use the logic of
vtd_dev_pt_enabled() to determine the passthrough mode in
vtd_do_iommu_translate().

Signed-off-by: Jason Wang 
---
 hw/i386/intel_iommu.c | 38 +++---
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f584449d8d..f346a82652 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1512,11 +1512,29 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace 
*vtd_as)
  * 1st-level translation or 2nd-level translation, it depends
  * on PGTT setting.
  */
-static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
+static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce)
+{
+VTDPASIDEntry pe;
+int ret;
+
+if (s->root_scalable) {
+ret = vtd_ce_get_rid2pasid_entry(s, ce, );
+if (ret) {
+error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
+  __func__, ret);
+return false;
+}
+return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
+}
+
+return (vtd_ce_get_type(ce) == VTD_CONTEXT_TT_PASS_THROUGH);
+
+}
+
+static bool vtd_as_pt_enabled(VTDAddressSpace *as)
 {
 IntelIOMMUState *s;
 VTDContextEntry ce;
-VTDPASIDEntry pe;
 int ret;
 
 assert(as);
@@ -1534,17 +1552,7 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
 return false;
 }
 
-if (s->root_scalable) {
-ret = vtd_ce_get_rid2pasid_entry(s, , );
-if (ret) {
-error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
-  __func__, ret);
-return false;
-}
-return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
-}
-
-return (vtd_ce_get_type() == VTD_CONTEXT_TT_PASS_THROUGH);
+return vtd_dev_pt_enabled(s, );
 }
 
 /* Return whether the device is using IOMMU translation. */
@@ -1556,7 +1564,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
 
 assert(as);
 
-use_iommu = as->iommu_state->dmar_enabled && !vtd_dev_pt_enabled(as);
+use_iommu = as->iommu_state->dmar_enabled && !vtd_as_pt_enabled(as);
 
 trace_vtd_switch_address_space(pci_bus_num(as->bus),
VTD_PCI_SLOT(as->devfn),
@@ -1749,7 +1757,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
*vtd_as, PCIBus *bus,
  * We don't need to translate for pass-through context entries.
  * Also, let's ignore IOTLB caching as well for PT devices.
  */
-if (vtd_ce_get_type() == VTD_CONTEXT_TT_PASS_THROUGH) {
+if (vtd_dev_pt_enabled(s, )) {
 entry->iova = addr & VTD_PAGE_MASK_4K;
 entry->translated_addr = entry->iova;
 entry->addr_mask = ~VTD_PAGE_MASK_4K;
-- 
2.25.1




Re: [PATCH 2/4] dma: Let ld*_dma() take MemTxAttrs argument

2021-12-21 Thread Cédric Le Goater

On 12/18/21 15:51, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling ld*_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé 



Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  include/hw/pci/pci.h   |  3 ++-
  include/hw/ppc/spapr_vio.h |  3 ++-
  include/sysemu/dma.h   | 11 ++-
  hw/intc/pnv_xive.c |  7 ---
  hw/usb/hcd-xhci.c  |  6 +++---
  5 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index d07e9707b48..0613308b1b6 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -854,7 +854,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, 
dma_addr_t addr,
  static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev,  \
 dma_addr_t addr) \
  {   \
-return ld##_l##_dma(pci_get_address_space(dev), addr);  \
+return ld##_l##_dma(pci_get_address_space(dev), addr,   \
+MEMTXATTRS_UNSPECIFIED);\
  }   \
  static inline void st##_s##_pci_dma(PCIDevice *dev, \
  dma_addr_t addr, uint##_bits##_t val) 
\
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index e87f8e6f596..d2ec9b0637f 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -126,7 +126,8 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, 
uint64_t taddr,
  (stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
  #define vio_stq(_dev, _addr, _val) \
  (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
-#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
+#define vio_ldq(_dev, _addr) \
+(ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED))
  
  int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
  
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h

index 2a60d2c5d61..b711d390a4f 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -242,10 +242,11 @@ static inline void dma_memory_unmap(AddressSpace *as,
  
  #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \

  static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, 
\
-dma_addr_t addr) \
+dma_addr_t addr, \
+MemTxAttrs attrs) \
  {   \
  uint##_bits##_t val;\
-dma_memory_read(as, addr, , (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \
+dma_memory_read(as, addr, , (_bits) / 8, attrs); \
  return _end##_bits##_to_cpu(val);   \
  }   \
  static inline void st##_sname##_##_end##_dma(AddressSpace *as,  \
@@ -254,14 +255,14 @@ static inline void dma_memory_unmap(AddressSpace *as,
   MemTxAttrs attrs)  \
  {   \
  val = cpu_to_##_end##_bits(val);\
-dma_memory_write(as, addr, , (_bits) / 8, attrs); \
+dma_memory_write(as, addr, , (_bits) / 8, attrs);   \
  }
  
-static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)

+static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs 
attrs)
  {
  uint8_t val;
  
-dma_memory_read(as, addr, , 1, MEMTXATTRS_UNSPECIFIED);

+dma_memory_read(as, addr, , 1, attrs);
  return val;
  }
  
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c

index ad43483612e..d9249bbc0c1 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
uint32_t type,
  
  /* Get the page size of the indirect table. */

  vsd_addr = vsd & VSD_ADDRESS_MASK;
-vsd = ldq_be_dma(_space_memory, vsd_addr);
+vsd = ldq_be_dma(_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
  
  if (!(vsd & VSD_ADDRESS_MASK)) {

  #ifdef XIVE_DEBUG
@@ -195,7 +195,8 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
uint32_t type,
  /* Load the VSD we are looking for, if not already done */
  if (vsd_idx) {
  vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE;
-vsd = ldq_be_dma(_space_memory, vsd_addr);
+vsd = ldq_be_dma(_space_memory, vsd_addr,
+ MEMTXATTRS_UNSPECIFIED);
  
  if (!(vsd & VSD_ADDRESS_MASK)) {

  

[PATCH 0/8] ppc/ppc405: Fixes

2021-12-21 Thread Cédric Le Goater
Hello,

The series starts with a couple of cleanups helpping debug. It then
adds back support for 405 timers which was broken 10 years ago.

Thanks,

C. 

Cédric Le Goater (8):
  target/ppc: Print out literal exception names in logs
  ppc/ppc4xx: Convert printfs()
  ppc/ppc405: Activate MMU logs
  ppc/ppc405: Restore TCR and STR write handlers
  ppc/ppc405: Rework ppc_40x_timers_init() to use a PowerPCCPU
  ppc/ppc405: Fix timer initialization
  ppc/ppc405: Introduce a store helper for SPR_40x_PID
  ppc/ppc405: Dump specific registers

 target/ppc/cpu.h |  2 +
 target/ppc/helper.h  |  2 +
 target/ppc/spr_tcg.h |  3 ++
 hw/ppc/mpc8544_guts.c|  9 +++--
 hw/ppc/ppc.c | 67 +---
 hw/ppc/ppc405_uc.c   |  2 -
 hw/ppc/ppc4xx_devs.c | 39 ++-
 hw/ppc/ppc4xx_pci.c  | 11 --
 target/ppc/cpu_init.c| 17 ++--
 target/ppc/excp_helper.c | 75 +++-
 target/ppc/mmu_common.c  |  4 +-
 target/ppc/mmu_helper.c  |  2 +-
 target/ppc/timebase_helper.c | 10 +
 target/ppc/translate.c   | 20 ++
 hw/ppc/trace-events  |  7 
 15 files changed, 203 insertions(+), 67 deletions(-)

-- 
2.31.1




[PATCH 3/5] ppc/pnv: Remove the PHB4 "device-id" property

2021-12-21 Thread Cédric Le Goater
It's unused.

Signed-off-by: Cédric Le Goater 
---
 include/hw/pci-host/pnv_phb4.h | 2 --
 hw/pci-host/pnv_phb4.c | 1 -
 hw/pci-host/pnv_phb4_pec.c | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 60de3031a622..4a19338db35e 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -84,7 +84,6 @@ struct PnvPHB4 {
 uint32_t phb_id;
 
 uint64_t version;
-uint16_t device_id;
 
 char bus_path[8];
 
@@ -222,7 +221,6 @@ struct PnvPhb4PecClass {
 const char *stk_compat;
 int stk_compat_size;
 uint64_t version;
-uint64_t device_id;
 const uint32_t *num_stacks;
 };
 
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 4caf03310fab..3b50a22b97cd 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1261,7 +1261,6 @@ static Property pnv_phb4_properties[] = {
 DEFINE_PROP_UINT32("index", PnvPHB4, phb_id, 0),
 DEFINE_PROP_UINT32("chip-id", PnvPHB4, chip_id, 0),
 DEFINE_PROP_UINT64("version", PnvPHB4, version, 0),
-DEFINE_PROP_UINT16("device-id", PnvPHB4, device_id, 0),
 DEFINE_PROP_LINK("stack", PnvPHB4, stack, TYPE_PNV_PHB4_PEC_STACK,
  PnvPhb4PecStack *),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index 24a3adcae326..f3e4fa0c8297 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -527,7 +527,6 @@ static void pnv_pec_class_init(ObjectClass *klass, void 
*data)
 pecc->stk_compat = stk_compat;
 pecc->stk_compat_size = sizeof(stk_compat);
 pecc->version = PNV_PHB4_VERSION;
-pecc->device_id = PNV_PHB4_DEVICE_ID;
 pecc->num_stacks = pnv_pec_num_stacks;
 }
 
@@ -587,8 +586,6 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 _fatal);
 object_property_set_int(OBJECT(>phb), "version", pecc->version,
 _fatal);
-object_property_set_int(OBJECT(>phb), "device-id", pecc->device_id,
-_fatal);
 object_property_set_link(OBJECT(>phb), "stack", OBJECT(stack),
  _abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(>phb), errp)) {
-- 
2.31.1




[PATCH 2/8] ppc/ppc4xx: Convert printfs()

2021-12-21 Thread Cédric Le Goater
Use a QEMU log primitive for errors and trace events for debug.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/mpc8544_guts.c |  9 ++---
 hw/ppc/ppc4xx_devs.c  | 39 +++
 hw/ppc/ppc4xx_pci.c   | 11 +++
 hw/ppc/trace-events   |  5 +
 4 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index e8d2d51c20c0..a26e83d0484b 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/module.h"
+#include "qemu/log.h"
 #include "sysemu/runstate.h"
 #include "cpu.h"
 #include "hw/sysbus.h"
@@ -82,7 +83,9 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
 value = env->spr[SPR_E500_SVR];
 break;
 default:
-fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Unknown register 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
 break;
 }
 
@@ -101,8 +104,8 @@ static void mpc8544_guts_write(void *opaque, hwaddr addr,
 }
 break;
 default:
-fprintf(stderr, "guts: Unknown register write: %x = %x\n",
-(int)addr, (unsigned)value);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown register 0x%" HWADDR_PRIx
+   " = 0x%" PRIx64 "\n", __func__, addr, value);
 break;
 }
 }
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 980c48944fc7..e7d82ae5016c 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -35,14 +35,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
-
-/*#define DEBUG_UIC*/
-
-#ifdef DEBUG_UIC
-#  define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
-#else
-#  define LOG_UIC(...) do { } while (0)
-#endif
+#include "trace.h"
 
 static void ppc4xx_reset(void *opaque)
 {
@@ -137,8 +130,9 @@ static uint32_t sdram_bcr (hwaddr ram_base,
 bcr = 0x000C;
 break;
 default:
-printf("%s: invalid RAM size " TARGET_FMT_plx "\n", __func__,
-   ram_size);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
+  ram_size);
 return 0x;
 }
 bcr |= ram_base & 0xFF80;
@@ -171,10 +165,8 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 {
 if (sdram->bcr[i] & 0x0001) {
 /* Unmap RAM */
-#ifdef DEBUG_SDRAM
-printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
 memory_region_del_subregion(get_system_memory(),
 >containers[i]);
 memory_region_del_subregion(>containers[i],
@@ -183,10 +175,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 }
 sdram->bcr[i] = bcr & 0xFFDEE001;
 if (enabled && (bcr & 0x0001)) {
-#ifdef DEBUG_SDRAM
-printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(bcr), sdram_size(bcr));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr));
 memory_region_init(>containers[i], NULL, "sdram-containers",
sdram_size(bcr));
 memory_region_add_subregion(>containers[i], 0,
@@ -216,10 +205,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
-#ifdef DEBUG_SDRAM
-printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
 memory_region_del_subregion(get_system_memory(),
 >ram_memories[i]);
 }
@@ -316,16 +303,12 @@ static void dcr_write_sdram (void *opaque, int dcrn, 
uint32_t val)
 case 0x20: /* SDRAM_CFG */
 val &= 0xFFE0;
 if (!(sdram->cfg & 0x8000) && (val & 0x8000)) {
-#ifdef DEBUG_SDRAM
-printf("%s: enable SDRAM controller\n", __func__);
-#endif
+trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
 sdram_map_bcr(sdram);
 sdram->status &= ~0x8000;
 } else if ((sdram->cfg & 0x8000) && !(val & 0x8000)) {
-#ifdef DEBUG_SDRAM
-printf("%s: disable SDRAM controller\n", __func__);
-#endif
+trace_ppc4xx_sdram_enable("disable");
 /* invalidate all RAM mappings */
 sdram_unmap_bcr(sdram);
 

[PATCH 3/8] ppc/ppc405: Activate MMU logs

2021-12-21 Thread Cédric Le Goater
There is no need to deactivate MMU logging at compile time.

Signed-off-by: Cédric Le Goater 
---
 target/ppc/mmu_common.c | 4 ++--
 target/ppc/mmu_helper.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 4e278365ca55..c0d3d32fafaa 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -34,9 +34,9 @@
 #include "mmu-book3s-v3.h"
 #include "mmu-radix64.h"
 
-/* #define DEBUG_MMU */
+#define DEBUG_MMU
 /* #define DEBUG_BATS */
-/* #define DEBUG_SOFTWARE_TLB */
+#define DEBUG_SOFTWARE_TLB
 /* #define DUMP_PAGE_TABLES */
 /* #define FLUSH_ALL_TLBS */
 
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 2ec3d203a081..6788577f449f 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -37,7 +37,7 @@
 #include "exec/cpu_ldst.h"
 
 /* #define DEBUG_BATS */
-/* #define DEBUG_SOFTWARE_TLB */
+#define DEBUG_SOFTWARE_TLB
 /* #define DUMP_PAGE_TABLES */
 /* #define FLUSH_ALL_TLBS */
 
-- 
2.31.1




[PATCH 5/5] ppc/pnv: Attach PHB4 root port device when defaults are enabled

2021-12-21 Thread Cédric Le Goater
This cleanups the PHB4 model a bit more since the root port is an
independent device and it will ease our task when adding user created
PHB4s.

Signed-off-by: Cédric Le Goater 
---
 include/hw/pci-host/pnv_phb4.h |  2 --
 hw/pci-host/pnv_phb4.c | 11 ---
 hw/ppc/pnv.c   |  9 -
 3 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 4a19338db35e..ea63df967678 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -78,8 +78,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(PnvPHB4, PNV_PHB4)
 struct PnvPHB4 {
 PCIExpressHost parent_obj;
 
-PnvPHB4RootPort root;
-
 uint32_t chip_id;
 uint32_t phb_id;
 
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 3b50a22b97cd..3b4758c42e26 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1158,12 +1158,6 @@ static void pnv_phb4_instance_init(Object *obj)
 
 /* XIVE interrupt source object */
 object_initialize_child(obj, "source", >xsrc, TYPE_XIVE_SOURCE);
-
-/* Root Port */
-object_initialize_child(obj, "root", >root, TYPE_PNV_PHB4_ROOT_PORT);
-
-qdev_prop_set_int32(DEVICE(>root), "addr", PCI_DEVFN(0, 0));
-qdev_prop_set_bit(DEVICE(>root), "multifunction", false);
 }
 
 static void pnv_phb4_realize(DeviceState *dev, Error **errp)
@@ -1207,11 +1201,6 @@ static void pnv_phb4_realize(DeviceState *dev, Error 
**errp)
 pci_setup_iommu(pci->bus, pnv_phb4_dma_iommu, phb);
 pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
 
-/* Add a single Root port */
-qdev_prop_set_uint8(DEVICE(>root), "chassis", phb->chip_id);
-qdev_prop_set_uint16(DEVICE(>root), "slot", phb->phb_id);
-qdev_realize(DEVICE(>root), BUS(pci->bus), _fatal);
-
 /* Setup XIVE Source */
 if (phb->big_phb) {
 nr_irqs = PNV_PHB4_MAX_INTs;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6edfd6876fd0..7a397698e984 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1403,7 +1403,7 @@ static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error 
**errp)
 static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp)
 {
 Pnv9Chip *chip9 = PNV9_CHIP(chip);
-int i;
+int i, j;
 
 for (i = 0; i < chip->num_pecs; i++) {
 PnvPhb4PecState *pec = >pecs[i];
@@ -1425,6 +1425,13 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, 
Error **errp)
 
 pnv_xscom_add_subregion(chip, pec_nest_base, >nest_regs_mr);
 pnv_xscom_add_subregion(chip, pec_pci_base, >pci_regs_mr);
+
+for (j = 0; j < pec->num_stacks; j++) {
+PnvPHB4 *phb = >stacks[j].phb;
+
+pnv_phb_attach_root_port(PCI_HOST_BRIDGE(phb), phb->phb_id,
+ TYPE_PNV_PHB4_ROOT_PORT);
+}
 }
 }
 
-- 
2.31.1




[PATCH 2/5] ppc/pnv: Remove PHB4 reset handler

2021-12-21 Thread Cédric Le Goater
The PHB4 reset handler was preparing ground for PHB5 to set
appropriately the device id. We don't need it for the PHB4 since the
device id is already set in the root port complex. PH5 will introduce
its own.

"device-id" property is now useless. It should be removed.

Signed-off-by: Cédric Le Goater 
---
 hw/pci-host/pnv_phb4.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 40b793201a34..4caf03310fab 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1229,18 +1229,6 @@ static void pnv_phb4_realize(DeviceState *dev, Error 
**errp)
 phb->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
 }
 
-static void pnv_phb4_reset(DeviceState *dev)
-{
-PnvPHB4 *phb = PNV_PHB4(dev);
-PCIDevice *root_dev = PCI_DEVICE(>root);
-
-/*
- * Configure PCI device id at reset using a property.
- */
-pci_config_set_vendor_id(root_dev->config, PCI_VENDOR_ID_IBM);
-pci_config_set_device_id(root_dev->config, phb->device_id);
-}
-
 static const char *pnv_phb4_root_bus_path(PCIHostState *host_bridge,
   PCIBus *rootbus)
 {
@@ -1290,7 +1278,6 @@ static void pnv_phb4_class_init(ObjectClass *klass, void 
*data)
 device_class_set_props(dc, pnv_phb4_properties);
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 dc->user_creatable  = false;
-dc->reset   = pnv_phb4_reset;
 
 xfc->notify = pnv_phb4_xive_notify;
 }
-- 
2.31.1




[PATCH 0/5] ppc/pnv: Preliminary cleanups before user created PHBs

2021-12-21 Thread Cédric Le Goater
Hello,

There are the last cleanups preparing ground for PHBs created on the
command line and possibly libvirt support.

Thanks,

C.

Cédric Le Goater (5):
  ppc/pnv: Change the maximum of PHB3 devices for Power8NVL
  ppc/pnv: Remove PHB4 reset handler
  ppc/pnv: Remove the PHB4 "device-id" property
  ppc/pnv: Attach PHB3 root port device when defaults are enabled
  ppc/pnv: Attach PHB4 root port device when defaults are enabled

 include/hw/pci-host/pnv_phb3.h |  2 --
 include/hw/pci-host/pnv_phb4.h |  4 
 hw/pci-host/pnv_phb3.c |  8 
 hw/pci-host/pnv_phb4.c | 25 -
 hw/pci-host/pnv_phb4_pec.c |  3 ---
 hw/ppc/pnv.c   | 25 +++--
 6 files changed, 23 insertions(+), 44 deletions(-)

-- 
2.31.1




[PATCH 6/8] ppc/ppc405: Fix timer initialization

2021-12-21 Thread Cédric Le Goater
Timers are already initialized in ppc4xx_init(). No need to do it a
second time with a wrong set.

Fixes: d715ea961254 ("PPC: 405: Fix ppc405ep initialization")
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405_uc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index ec97b22bd019..8aacd275a652 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1461,8 +1461,6 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
 ppc4xx_pob_init(env);
 /* OBP arbitrer */
 ppc4xx_opba_init(0xef600600);
-/* Initialize timers */
-ppc_booke_timers_init(cpu, sysclk, 0);
 /* Universal interrupt controller */
 uicdev = qdev_new(TYPE_PPC_UIC);
 uicsbd = SYS_BUS_DEVICE(uicdev);
-- 
2.31.1




[PATCH 4/5] ppc/pnv: Attach PHB3 root port device when defaults are enabled

2021-12-21 Thread Cédric Le Goater
This cleanups the PHB3 model a bit more since the root port is an
independent device and it will ease our task when adding user created
PHB3s.

Signed-off-by: Cédric Le Goater 
---
 include/hw/pci-host/pnv_phb3.h |  2 --
 hw/pci-host/pnv_phb3.c |  8 
 hw/ppc/pnv.c   | 14 ++
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h
index e9c13e6bd821..2e423c3890bc 100644
--- a/include/hw/pci-host/pnv_phb3.h
+++ b/include/hw/pci-host/pnv_phb3.h
@@ -155,8 +155,6 @@ struct PnvPHB3 {
 
 PnvPBCQState pbcq;
 
-PnvPHB3RootPort root;
-
 QLIST_HEAD(, PnvPhb3DMASpace) dma_spaces;
 
 PnvChip *chip;
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 9c4451ca0d1c..39f03bd256d0 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -980,10 +980,6 @@ static void pnv_phb3_instance_init(Object *obj)
 /* Power Bus Common Queue */
 object_initialize_child(obj, "pbcq", >pbcq, TYPE_PNV_PBCQ);
 
-/* Root Port */
-object_initialize_child(obj, "root", >root, TYPE_PNV_PHB3_ROOT_PORT);
-qdev_prop_set_int32(DEVICE(>root), "addr", PCI_DEVFN(0, 0));
-qdev_prop_set_bit(DEVICE(>root), "multifunction", false);
 }
 
 static void pnv_phb3_realize(DeviceState *dev, Error **errp)
@@ -1051,10 +1047,6 @@ static void pnv_phb3_realize(DeviceState *dev, Error 
**errp)
 
 pci_setup_iommu(pci->bus, pnv_phb3_dma_iommu, phb);
 
-/* Add a single Root port */
-qdev_prop_set_uint8(DEVICE(>root), "chassis", phb->chip_id);
-qdev_prop_set_uint16(DEVICE(>root), "slot", phb->phb_id);
-qdev_realize(DEVICE(>root), BUS(pci->bus), _fatal);
 }
 
 void pnv_phb3_update_regions(PnvPHB3 *phb)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 9de8b8353014..6edfd6876fd0 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1156,6 +1156,17 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error 
**errp)
 }
 }
 
+/* Attach a root port device */
+static void pnv_phb_attach_root_port(PCIHostState *pci, int id,
+ const char *name)
+{
+PCIDevice *root = pci_new(PCI_DEVFN(0, 0), name);
+
+qdev_prop_set_uint8(>qdev, "chassis", id);
+qdev_prop_set_uint16(>qdev, "slot", id);
+pci_realize_and_unref(root, pci->bus, _fatal);
+}
+
 static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
 {
 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
@@ -1250,6 +1261,9 @@ static void pnv_chip_power8_realize(DeviceState *dev, 
Error **errp)
 if (!sysbus_realize(SYS_BUS_DEVICE(phb), errp)) {
 return;
 }
+
+pnv_phb_attach_root_port(PCI_HOST_BRIDGE(phb), phb->phb_id,
+ TYPE_PNV_PHB3_ROOT_PORT);
 }
 }
 
-- 
2.31.1




[PATCH 1/5] ppc/pnv: Change the maximum of PHB3 devices for Power8NVL

2021-12-21 Thread Cédric Le Goater
The POWER8 processors with a NVLink logic unit have 4 PHB3 devices per
chip.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/pnv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 29ee0d0f08b4..9de8b8353014 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1314,7 +1314,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 
 k->chip_cfam_id = 0x120d30498000ull;  /* P8 Naples DD1.0 */
 k->cores_mask = POWER8_CORE_MASK;
-k->num_phbs = 3;
+k->num_phbs = 4;
 k->core_pir = pnv_chip_core_pir_p8;
 k->intc_create = pnv_chip_power8_intc_create;
 k->intc_reset = pnv_chip_power8_intc_reset;
-- 
2.31.1




Re: [PATCH] vl: Add -set options to device opts dict when using JSON syntax for -device

2021-12-21 Thread MkfsSion
On 2021/12/21 19:26, Markus Armbruster wrote:> Two issues, and only looks 
fixable.
> 
> -device accepts either a QemuOpts or a JSON argument.
> 
> It parses the former with qemu_opts_parse_noisily() into a QemuOpt
> stored in @qemu_device_opts.
> 
> It parses the latter with qobject_from_json() into a QObject stored in
> @device_opts.  Yes, the names are confusing.
> 
> -set parses its argument into @group, @id, and @arg (the value).
> 
> Before the patch, it uses @group and @id to look up the QemuOpt in
> @qemu_device_opts.  If found, it updates it with qemu_opt_set().
> 
> By design, -set operates on the QemuOpts store.
> 
> Options stored in @device_opts are not found.  Your patch tries to fix
> that.  Before I can explain what's wrong with it, I need more
> background.
> 
> QemuOpts arguments are parsed as a set of (key, value) pairs, where the
> values are all strings (because qemu_device_opts.desc[] is empty).  We
> access them with a qobject_input_visitor_new_keyval() visitor.  This
> parses the strings according to the types being visited.
> 
> Example: key=42 gets stored as {"key": "42"}.  If we visit it with
> visit_type_str(), we use string value "42".  If we visit it with
> visit_type_int() or similar, we use integer value 42.  If we visit it
> with visit_type_number(), we use double value 42.0.  If we visit it with
> something else, we error out.
> 
> JSON arguments are parsed as arbitrary JSON object.  We access them with
> a qobject_input_visitor_new() visitor.  This expects the values to have
> JSON types appropriate for the types being visited.
> 
> Example: {"key": "42"} gets stored as is.  Now everything but
> visit_type_str() errors out.
> 
Thanks for the detailed explanation. Since I am new to QEMU codebase, I did not 
notice that the visitor is different when -device JSON syntax is used. 
> Back to your patch.  It adds code to look up a QObject in @device_opts.
> If found, it updates it.
> 
> Issue#1: it does so regardless of @group.
> 
> Example:
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -M q35,usb=on -device 
> '{"driver": "usb-mouse", "id": "ms0"}' -set chardev.ms0.serial=456
> 
> Here, -set chardev... gets misinterpreted as -set device...
> 
Oh, I forgot to match the group name.
> Issue#2 is the value to store in @device_opts.  Always storing a string,
> like in the QemuOpts case, would be wrong, because it works only when
> its accessed with visit_type_str(), i.e. the property is actually of
> string type.
> 
> Example:
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -M q35,usb=on -device 
> '{"driver": "usb-mouse", "id": "ms0"}' -set device.ms0.serial=123
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -M q35,usb=on -device 
> '{"driver": "usb-mouse", "id": "ms0"}' -set device.ms0.msos-desc=off
> qemu-system-x86_64: -device {"driver": "usb-mouse", "id": "ms0"}: Invalid 
> parameter type for 'msos-desc', expected: boolean
> 
> Your patch stores a boolean if possible, else a number if possible, else
> a string.  This is differently wrong.
> 
> Example:
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -M q35,usb=on -device 
> '{"driver": "usb-mouse", "id": "ms0"}'
> 
> Example:
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -M q35,usb=on -device 
> '{"driver": "usb-mouse", "id": "ms0"}' -set device.ms0.serial=123
> qemu-system-x86_64: -device {"driver": "usb-mouse", "id": "ms0", 
> "serial": "123"}: Invalid parameter type for 'serial', expected: string
> 
> I can't see how -set can store the right thing.
> 
> Aside: the error messages refer to -device instead of -set.  Known bug
> in -set, hard to fix.
> There seems no way to know what type of value the property actually take. I 
> am trying to add a QDict* parameter in qdev_device_add_from_qdict() function 
> and set thoses properties via object_set_properties_from_keyval() call but 
> with false option for from_json argument, which will use 
> qobject_input_visitor_new_keyval() visitor for the properties provided via 
> -set option. Maybe the issue can be fixed in that way.



Re: [RFC PATCH v3 18/27] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)

2021-12-21 Thread yangxiaojuan
Hi, Mark

On 12/18/2021 08:33 AM, Mark Cave-Ayland wrote:
> On 04/12/2021 12:07, Xiaojuan Yang wrote:
> 
>> This patch realize the PCH-PIC interrupt controller.
>>
>> Signed-off-by: Xiaojuan Yang 
>> Signed-off-by: Song Gao 
>> ---
>>   hw/intc/Kconfig |   4 +
>>   hw/intc/loongarch_pch_pic.c | 357 
>>   hw/intc/meson.build |   1 +
>>   hw/intc/trace-events|   5 +
>>   hw/loongarch/Kconfig|   1 +
>>   include/hw/intc/loongarch_pch_pic.h |  61 +
>>   6 files changed, 429 insertions(+)
>>   create mode 100644 hw/intc/loongarch_pch_pic.c
>>   create mode 100644 include/hw/intc/loongarch_pch_pic.h
>>
>> diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
>> index 511dcac537..96da13ad1d 100644
>> --- a/hw/intc/Kconfig
>> +++ b/hw/intc/Kconfig
>> @@ -76,3 +76,7 @@ config M68K_IRQC
>> config LOONGARCH_IPI
>>   bool
>> +
>> +config LOONGARCH_PCH_PIC
>> +bool
>> +select UNIMP
>> diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
>> new file mode 100644
>> index 00..2ede29ceb0
>> --- /dev/null
>> +++ b/hw/intc/loongarch_pch_pic.c
>> @@ -0,0 +1,357 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * QEMU Loongson 7A1000 I/O interrupt controller.
>> + *
>> + * Copyright (C) 2021 Loongson Technology Corporation Limited
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/loongarch/loongarch.h"
>> +#include "hw/irq.h"
>> +#include "hw/intc/loongarch_pch_pic.h"
>> +#include "migration/vmstate.h"
>> +#include "trace.h"
>> +
>> +#define for_each_set_bit(bit, addr, size) \
>> + for ((bit) = find_first_bit((addr), (size));\
>> +  (bit) < (size);\
>> +  (bit) = find_next_bit((addr), (size), (bit) + 1))
>> +
>> +static void pch_pic_update_irq(loongarch_pch_pic *s, uint64_t mask, int 
>> level)
>> +{
>> +int i;
>> +uint64_t val;
>> +val = mask & s->intirr & (~s->int_mask);
>> +
>> +for_each_set_bit(i, , 64) {
>> +if (level == 1) {
>> +if ((s->intisr & (0x1ULL << i)) == 0) {
>> +s->intisr |= 1ULL << i;
>> +qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1);
>> +}
>> +} else if (level == 0) {
>> +if (s->intisr & (0x1ULL << i)) {
>> +s->intisr &= ~(0x1ULL << i);
>> +qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0);
>> +}
>> +}
>> +}
>> +}
> 
> The normal pattern would be to use something like:
> 
> for (i = 0; i < 64; i++) {
> if (level) {
> s->intisr |= 1ULL << i;
> } else {
> s->intisr &= ~(0x1ULL << i);
> }
> 
> qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], level);
> }
> 
> Why is it necessary to check the previous value of (s->intisr & (0x1ULL << 
> i)) here?

Here check the previous value to avoid Unnecessary write. It seems make things 
more complicated. I will modify

> 
>> +static void pch_pic_irq_handler(void *opaque, int irq, int level)
>> +{
>> +loongarch_pch_pic *s = LOONGARCH_PCH_PIC(opaque);
>> +
>> +assert(irq < PCH_PIC_IRQ_NUM);
>> +uint64_t mask = 1ULL << irq;
>> +
>> +trace_pch_pic_irq_handler(s->intedge, irq, level);
>> +
>> +if (s->intedge & mask) {
>> +/* Edge triggered */
>> +if (level) {
>> +if ((s->last_intirr & mask) == 0) {
>> +s->intirr |= mask;
>> +}
>> +s->last_intirr |= mask;
>> +} else {
>> +s->last_intirr &= ~mask;
>> +}
>> +} else {
>> +/* Level triggered */
>> +if (level) {
>> +s->intirr |= mask;
>> +s->last_intirr |= mask;
>> +} else {
>> +s->intirr &= ~mask;
>> +s->last_intirr &= ~mask;
>> +}
>> +
>> +}
>> +pch_pic_update_irq(s, mask, level);
>> +}
>> +
>> +static uint64_t loongarch_pch_pic_reg_read(void *opaque, hwaddr addr,
>> +   unsigned size)
>> +{
>> +loongarch_pch_pic *s = LOONGARCH_PCH_PIC(opaque);
>> +uint64_t val = 0;
>> +uint32_t offset = addr & 0xfff;
>> +int64_t offset_tmp;
>> +
>> +if (size == 8) {
>> +switch (offset) {
>> +case PCH_PIC_INT_ID_OFFSET:
>> +val = (PCH_PIC_INT_ID_NUM << 32) | PCH_PIC_INT_ID_VAL;
>> +break;
>> +case PCH_PIC_INT_MASK_OFFSET:
>> +val =  s->int_mask;
>> +break;
>> +case PCH_PIC_INT_STATUS_OFFSET:
>> +val = s->intisr & (~s->int_mask);
>> +break;
>> +case PCH_PIC_INT_EDGE_OFFSET:
>> +val = s->intedge;
>> +break;
>> +case PCH_PIC_INT_POL_OFFSET:
>> +val = s->int_polarity;
>> +break;
>> +case PCH_PIC_HTMSI_EN_OFFSET...PCH_PIC_HTMSI_EN_END:
>> +val = 

[PATCH] Supporting AST2600 HACE engine accumulative mode

2021-12-21 Thread Troy Lee
Accumulative mode will supply a initial state and append padding bit at
the end of hash stream.  However, the crypto library will padding those
bit automatically, so ripped it off from iov array.

Signed-off-by: Troy Lee 
---
 hw/misc/aspeed_hace.c | 30 --
 include/hw/misc/aspeed_hace.h |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 10f00e65f4..7c1794d6d0 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -27,6 +27,7 @@
 
 #define R_HASH_SRC  (0x20 / 4)
 #define R_HASH_DEST (0x24 / 4)
+#define R_HASH_KEY_BUFF (0x28 / 4)
 #define R_HASH_SRC_LEN  (0x2c / 4)
 
 #define R_HASH_CMD  (0x30 / 4)
@@ -94,7 +95,10 @@ static int hash_algo_lookup(uint32_t reg)
 return -1;
 }
 
-static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode)
+static void do_hash_operation(AspeedHACEState *s,
+  int algo,
+  bool sg_mode,
+  bool acc_mode)
 {
 struct iovec iov[ASPEED_HACE_MAX_SG];
 g_autofree uint8_t *digest_buf;
@@ -103,6 +107,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, 
bool sg_mode)
 
 if (sg_mode) {
 uint32_t len = 0;
+uint32_t total_len = 0;
 
 for (i = 0; !(len & SG_LIST_LEN_LAST); i++) {
 uint32_t addr, src;
@@ -127,6 +132,21 @@ static void do_hash_operation(AspeedHACEState *s, int 
algo, bool sg_mode)
 plen = iov[i].iov_len;
 iov[i].iov_base = address_space_map(>dram_as, addr, , 
false,
 MEMTXATTRS_UNSPECIFIED);
+
+total_len += plen;
+if (acc_mode && len & SG_LIST_LEN_LAST) {
+/*
+ * Read the message length in bit from last 64/128 bits
+ * and tear the padding bits from iov
+ */
+uint64_t stream_len;
+
+memcpy(_len, iov[i].iov_base + iov[i].iov_len - 8, 8);
+stream_len = __bswap_64(stream_len) / 8;
+
+if (total_len > stream_len)
+iov[i].iov_len -= total_len - stream_len;
+}
 }
 } else {
 hwaddr len = s->regs[R_HASH_SRC_LEN];
@@ -210,6 +230,9 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, 
uint64_t data,
 case R_HASH_DEST:
 data &= ahc->dest_mask;
 break;
+case R_HASH_KEY_BUFF:
+data &= ahc->key_mask;
+break;
 case R_HASH_SRC_LEN:
 data &= 0x0FFF;
 break;
@@ -234,7 +257,7 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, 
uint64_t data,
 __func__, data & ahc->hash_mask);
 break;
 }
-do_hash_operation(s, algo, data & HASH_SG_EN);
+do_hash_operation(s, algo, data & HASH_SG_EN, data & 
HASH_DIGEST_ACCUM);
 
 if (data & HASH_IRQ_EN) {
 qemu_irq_raise(s->irq);
@@ -333,6 +356,7 @@ static void aspeed_ast2400_hace_class_init(ObjectClass 
*klass, void *data)
 
 ahc->src_mask = 0x0FFF;
 ahc->dest_mask = 0x0FF8;
+ahc->key_mask = 0x0FC0;
 ahc->hash_mask = 0x03ff; /* No SG or SHA512 modes */
 }
 
@@ -351,6 +375,7 @@ static void aspeed_ast2500_hace_class_init(ObjectClass 
*klass, void *data)
 
 ahc->src_mask = 0x3fff;
 ahc->dest_mask = 0x3ff8;
+ahc->key_mask = 0x3FC0;
 ahc->hash_mask = 0x03ff; /* No SG or SHA512 modes */
 }
 
@@ -369,6 +394,7 @@ static void aspeed_ast2600_hace_class_init(ObjectClass 
*klass, void *data)
 
 ahc->src_mask = 0x7FFF;
 ahc->dest_mask = 0x7FF8;
+ahc->key_mask = 0x7FF8;
 ahc->hash_mask = 0x00147FFF;
 }
 
diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index 94d5ada95f..2242945eb4 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -37,6 +37,7 @@ struct AspeedHACEClass {
 
 uint32_t src_mask;
 uint32_t dest_mask;
+uint32_t key_mask;
 uint32_t hash_mask;
 };
 
-- 
2.25.1




[PATCH v2 4/5] ui/sdl2: pass horizontal scroll information to the device code

2021-12-21 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/sdl2.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 17c0ec30eb..19bbc1fdd4 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -33,6 +33,7 @@
 #include "sysemu/runstate-action.h"
 #include "sysemu/sysemu.h"
 #include "ui/win32-kbd-hook.h"
+#include "qemu/log.h"
 
 static int sdl2_num_outputs;
 static struct sdl2_console *sdl2_console;
@@ -535,6 +536,10 @@ static void handle_mousewheel(SDL_Event *ev)
 btn = INPUT_BUTTON_WHEEL_UP;
 } else if (wev->y < 0) {
 btn = INPUT_BUTTON_WHEEL_DOWN;
+} else if (wev->x < 0) {
+btn = INPUT_BUTTON_WHEEL_RIGHT;
+} else if (wev->x > 0) {
+btn = INPUT_BUTTON_WHEEL_LEFT;
 } else {
 return;
 }
-- 
2.32.0




[PATCH v2 3/5] ui/gtk: pass horizontal scroll information to the device code

2021-12-21 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/gtk.c | 54 ++
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 428f02f2df..b52eec6fe9 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -963,33 +963,63 @@ static gboolean gd_scroll_event(GtkWidget *widget, 
GdkEventScroll *scroll,
 void *opaque)
 {
 VirtualConsole *vc = opaque;
-InputButton btn;
+InputButton btn_vertical;
+InputButton btn_horizontal;
+bool has_vertical = false;
+bool has_horizontal = false;
 
 if (scroll->direction == GDK_SCROLL_UP) {
-btn = INPUT_BUTTON_WHEEL_UP;
+btn_vertical = INPUT_BUTTON_WHEEL_UP;
+has_vertical = true;
 } else if (scroll->direction == GDK_SCROLL_DOWN) {
-btn = INPUT_BUTTON_WHEEL_DOWN;
+btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
+has_vertical = true;
+} else if (scroll->direction == GDK_SCROLL_LEFT) {
+btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
+has_horizontal = true;
+} else if (scroll->direction == GDK_SCROLL_RIGHT) {
+btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
+has_horizontal = true;
 } else if (scroll->direction == GDK_SCROLL_SMOOTH) {
 gdouble delta_x, delta_y;
 if (!gdk_event_get_scroll_deltas((GdkEvent *)scroll,
  _x, _y)) {
 return TRUE;
 }
-if (delta_y == 0) {
-return TRUE;
-} else if (delta_y > 0) {
-btn = INPUT_BUTTON_WHEEL_DOWN;
+
+if (delta_y > 0) {
+btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
+has_vertical = true;
+} else if (delta_y < 0) {
+btn_vertical = INPUT_BUTTON_WHEEL_UP;
+has_vertical = true;
+} else if (delta_x > 0) {
+btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
+has_horizontal = true;
+} else if (delta_x < 0) {
+btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
+has_horizontal = true;
 } else {
-btn = INPUT_BUTTON_WHEEL_UP;
+return TRUE;
 }
 } else {
 return TRUE;
 }
 
-qemu_input_queue_btn(vc->gfx.dcl.con, btn, true);
-qemu_input_event_sync();
-qemu_input_queue_btn(vc->gfx.dcl.con, btn, false);
-qemu_input_event_sync();
+if (has_vertical) {
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, true);
+qemu_input_event_sync();
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, false);
+qemu_input_event_sync();
+}
+
+if (has_horizontal) {
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, true);
+qemu_input_event_sync();
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, false);
+qemu_input_event_sync();
+}
+
 return TRUE;
 }
 
-- 
2.32.0




[PATCH v2 5/5] ui/input-legacy: pass horizontal scroll information

2021-12-21 Thread Dmitry Petrov
This code seems to be used by vmport hack, passing these values allows
to implement horizontal scroll support even when using vmport.
In case it's not supported horizontal scroll will act as a vertical one.

Signed-off-by: Dmitry Petrov 
---
 ui/input-legacy.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index 9fc78a639b..2c9a215d7f 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "qapi/qapi-commands-ui.h"
 #include "ui/console.h"
 #include "keymaps.h"
@@ -179,6 +180,20 @@ static void legacy_mouse_event(DeviceState *dev, 
QemuConsole *src,
 1,
 s->buttons);
 }
+if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
+s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
+s->axis[INPUT_AXIS_X],
+s->axis[INPUT_AXIS_Y],
+-2,
+s->buttons);
+}
+if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
+s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
+s->axis[INPUT_AXIS_X],
+s->axis[INPUT_AXIS_Y],
+2,
+s->buttons);
+}
 break;
 case INPUT_EVENT_KIND_ABS:
 move = evt->u.abs.data;
@@ -216,6 +231,7 @@ QEMUPutMouseEntry 
*qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
 QEMUPutMouseEntry *s;
 
 s = g_new0(QEMUPutMouseEntry, 1);
+qemu_log("qemu_add_mouse_event_handler %s", name);
 
 s->qemu_put_mouse_event = func;
 s->qemu_put_mouse_event_opaque = opaque;
-- 
2.32.0




[PATCH v2 2/5] ui/cocoa: pass horizontal scroll information to the device code

2021-12-21 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/cocoa.m | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 68a6302184..22a1f6776e 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -970,21 +970,27 @@ QemuCocoaView *cocoaView;
  */
 
 /*
- * When deltaY is zero, it means that this scrolling event was
- * either horizontal, or so fine that it only appears in
- * scrollingDeltaY. So we drop the event.
+ * We shouldn't have got a scroll event when deltaY and delta Y
+ * are zero, hence no harm in dropping the event
  */
-if ([event deltaY] != 0) {
+if ([event deltaY] != 0 || [event deltaX] != 0) {
 /* Determine if this is a scroll up or scroll down event */
-buttons = ([event deltaY] > 0) ?
+if ([event deltaY] != 0) {
+  buttons = ([event deltaY] > 0) ?
 INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
+} else if ([event deltaX] != 0) {
+  buttons = ([event deltaX] > 0) ?
+INPUT_BUTTON_WHEEL_LEFT : INPUT_BUTTON_WHEEL_RIGHT;
+}
+
 qemu_input_queue_btn(dcl.con, buttons, true);
 qemu_input_event_sync();
 qemu_input_queue_btn(dcl.con, buttons, false);
 qemu_input_event_sync();
 }
+
 /*
- * Since deltaY also reports scroll wheel events we prevent mouse
+ * Since deltaX/deltaY also report scroll wheel events we prevent 
mouse
  * movement code from executing.
  */
 mouse_event = false;
-- 
2.32.0




Re: [PATCH] ps2: Initial horizontal scroll support

2021-12-21 Thread Dmitry Petrov
Hi Marc-André,

Thank you for the review! It's much clearer to me now.

The odd thing about docs is that I wasn't able to find any specification
that would describe
intellimouse 4.0 protocol extension the way it's implemented in the linux
kernel.

For example here: https://isdaman.com/alsos/hardware/mouse/ps2interface.htm

> You may have seen mice with two scrolling wheels--one vertical and the
other horizontal.  These mice use the Microsoft Intellimouse data packet
format as described above.  If the vertical wheel is scrolled upward, the
Z-counter is incremented by one and if that wheel is scrolled down, the
Z-counter is decremented by one.  This is normal operation for a scrolling
wheel.  However, if the horizontal wheel is scrolled right, the Z-counter
is incremented by two and if it is scrolled left, the Z-counter is
decremented by two.  This seems like an odd way to implement the second
scrolling wheel, but it works since the placement of the two wheels make it
impossible to use both of them at the same time (and if you try to trick
the software and use both at the same time, it will ignore the horizontal
wheel.)

The closest thing I could find was a small hint on the osdev wiki:
https://wiki.osdev.org/Mouse_Input#Formats_of_Optional_4th_Packet_Byte

>  Note: if the buttons do not exist, then these bits may flip based on
scroll wheel movement! (ie. Be careful that this does not generate spurious
"mouse button click" events for buttons that do not exist.

After all the investigation I decided to simply mimic the linux kernel
behaviour and keep the comment from the original patch regarding the
buttons.

I will rephrase comments a bit, split the patch into a sequence and
resubmit.

Thanks a lot! Dmitry Petrov

On Tue, 21 Dec 2021 at 09:59, Marc-André Lureau 
wrote:

> Hi
>
> On Tue, Dec 21, 2021 at 4:10 AM Dmitry Petrov  wrote:
>
>> This patch introduces horizontal scroll support for the ps/2 mouse.
>> It includes changes in the ps/2 device driver as well as support
>> for three display options - cocoa, gtk and sdl, tested and working
>> on all of them against guest ubuntu system.
>>
>> The patch is based on the previous work by Brad Jorsch done in 2010
>> but never merge, see
>> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579968
>
>
> You should split the patch for the different subsystems/ui etc
>
> Looks good to me, although I didn't test it yet. Some comments below
>
>
>>
>> Signed-off-by: Dmitry Petrov 
>> ---
>>  hw/input/ps2.c| 54 ---
>>  qapi/ui.json  |  2 +-
>>  ui/cocoa.m| 18 ++--
>>  ui/gtk.c  | 54 ---
>>  ui/input-legacy.c | 16 ++
>>  ui/sdl2.c |  5 +
>>  6 files changed, 122 insertions(+), 27 deletions(-)
>>
>> diff --git a/hw/input/ps2.c b/hw/input/ps2.c
>> index 9376a8f4ce..9e42284cd9 100644
>> --- a/hw/input/ps2.c
>> +++ b/hw/input/ps2.c
>> @@ -123,6 +123,7 @@ typedef struct {
>>  int mouse_dx; /* current values, needed for 'poll' mode */
>>  int mouse_dy;
>>  int mouse_dz;
>> +int mouse_dw;
>>  uint8_t mouse_buttons;
>>  } PS2MouseState;
>>
>> @@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
>>  /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
>>  const int needed = s->mouse_type ? 4 : 3;
>>  unsigned int b;
>> -int dx1, dy1, dz1;
>> +int dx1, dy1, dz1, dw1;
>>
>>  if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
>>  return 0;
>> @@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
>>  dx1 = s->mouse_dx;
>>  dy1 = s->mouse_dy;
>>  dz1 = s->mouse_dz;
>> +dw1 = s->mouse_dw;
>>  /* XXX: increase range to 8 bits ? */
>>  if (dx1 > 127)
>>  dx1 = 127;
>> @@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
>>  /* extra byte for IMPS/2 or IMEX */
>>  switch(s->mouse_type) {
>>  default:
>> +/* Just ignore the wheels if not supported */
>> +s->mouse_dz = 0;
>> +s->mouse_dw = 0;
>>  break;
>>  case 3:
>>  if (dz1 > 127)
>> @@ -747,13 +752,38 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
>>  else if (dz1 < -127)
>>  dz1 = -127;
>>  ps2_queue_noirq(>common, dz1 & 0xff);
>> +s->mouse_dz -= dz1;
>> +s->mouse_dw = 0;
>>  break;
>>  case 4:
>> -if (dz1 > 7)
>> -dz1 = 7;
>> -else if (dz1 < -7)
>> -dz1 = -7;
>> -b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
>> +/*
>> + * This matches what the Linux kernel expects for exps/2 in
>> + * drivers/input/mouse/psmouse-base.c. Note, if you happen to
>> + * press/release the 4th or 5th buttons at the same moment as a
>> + * horizontal wheel scroll, those button presses will get lost.
>> I'm not
>> + * sure what to do about that, since by 

[PATCH v2 1/5] ps2: Initial horizontal scroll support

2021-12-21 Thread Dmitry Petrov
v2:
  - Patch is split into a sequence
  - value is clamped to 31 for horizontal scroll

This patch introduces horizontal scroll support for the ps/2
mouse.

The patch is based on the previous work
by Brad Jorsch done in 2010
but never merge, see
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579968

This change adds support for horizontal scroll to ps/2 mouse device
code. The code is implemented to match the logic of linux kernel
which is used as a reference.

Signed-off-by: Dmitry Petrov 
---
 hw/input/ps2.c | 57 +++---
 qapi/ui.json   |  2 +-
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 9376a8f4ce..6236711e1b 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -123,6 +123,7 @@ typedef struct {
 int mouse_dx; /* current values, needed for 'poll' mode */
 int mouse_dy;
 int mouse_dz;
+int mouse_dw;
 uint8_t mouse_buttons;
 } PS2MouseState;
 
@@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
 const int needed = s->mouse_type ? 4 : 3;
 unsigned int b;
-int dx1, dy1, dz1;
+int dx1, dy1, dz1, dw1;
 
 if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
 return 0;
@@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 dx1 = s->mouse_dx;
 dy1 = s->mouse_dy;
 dz1 = s->mouse_dz;
+dw1 = s->mouse_dw;
 /* XXX: increase range to 8 bits ? */
 if (dx1 > 127)
 dx1 = 127;
@@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* extra byte for IMPS/2 or IMEX */
 switch(s->mouse_type) {
 default:
+/* Just ignore the wheels if not supported */
+s->mouse_dz = 0;
+s->mouse_dw = 0;
 break;
 case 3:
 if (dz1 > 127)
@@ -747,13 +752,41 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 else if (dz1 < -127)
 dz1 = -127;
 ps2_queue_noirq(>common, dz1 & 0xff);
+s->mouse_dz -= dz1;
+s->mouse_dw = 0;
 break;
 case 4:
-if (dz1 > 7)
-dz1 = 7;
-else if (dz1 < -7)
-dz1 = -7;
-b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+/*
+ * This matches what the Linux kernel expects for exps/2 in
+ * drivers/input/mouse/psmouse-base.c. Note, if you happen to
+ * press/release the 4th or 5th buttons at the same moment as a
+ * horizontal wheel scroll, those button presses will get lost. I'm not
+ * sure what to do about that, since by this point we don't know
+ * whether those buttons actually changed state.
+ */
+if (dw1 != 0) {
+if (dw1 > 31) {
+dw1 = 31;
+} else if (dw1 < -31) {
+dw1 = -31;
+}
+
+/*
+ * linux kernel expects first 6 bits to represent the value
+ * for horizontal scroll
+ */
+b = (dw1 & 0x3f) | 0x40;
+s->mouse_dw -= dw1;
+} else {
+if (dz1 > 7) {
+dz1 = 7;
+} else if (dz1 < -7) {
+dz1 = -7;
+}
+
+b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+s->mouse_dz -= dz1;
+}
 ps2_queue_noirq(>common, b);
 break;
 }
@@ -764,7 +797,6 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* update deltas */
 s->mouse_dx -= dx1;
 s->mouse_dy -= dy1;
-s->mouse_dz -= dz1;
 
 return 1;
 }
@@ -806,6 +838,12 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole 
*src,
 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 s->mouse_dz++;
 }
+
+if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
+s->mouse_dw--;
+} else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
+s->mouse_dw++;
+}
 } else {
 s->mouse_buttons &= ~bmap[btn->button];
 }
@@ -833,8 +871,10 @@ static void ps2_mouse_sync(DeviceState *dev)
 /* if not remote, send event. Multiple events are sent if
too big deltas */
 while (ps2_mouse_send_packet(s)) {
-if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
+if (s->mouse_dx == 0 && s->mouse_dy == 0
+&& s->mouse_dz == 0 && s->mouse_dw == 0) {
 break;
+}
 }
 }
 }
@@ -1036,6 +1076,7 @@ static void ps2_mouse_reset(void *opaque)
 s->mouse_dx = 0;
 s->mouse_dy = 0;
 s->mouse_dz = 0;
+s->mouse_dw = 0;
 s->mouse_buttons = 0;
 }
 
diff --git a/qapi/ui.json b/qapi/ui.json
index d7567ac866..9dac1bf548 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -905,7 +905,7 @@
 ##
 { 'enum'  : 'InputButton',
   'data'  : [ 'left', 'middle', 'right', 'wheel-up', 

Re: [PATCH v3 00/15] KVM: mm: fd-based approach for supporting KVM guest private memory

2021-12-21 Thread Chao Peng
On Tue, Dec 21, 2021 at 03:44:40PM +, Sean Christopherson wrote:
> On Tue, Dec 21, 2021, Chao Peng wrote:
> > This is the third version of this series which try to implement the
> > fd-based KVM guest private memory.
> 
> ...
> 
> > Test
> > 
> > This code has been tested with latest TDX code patches hosted at
> > (https://github.com/intel/tdx/tree/kvm-upstream) with minimal TDX
> > adaption and QEMU support.
> > 
> > Example QEMU command line:
> > -object tdx-guest,id=tdx \
> > -object memory-backend-memfd-private,id=ram1,size=2G \
> > -machine 
> > q35,kvm-type=tdx,pic=no,kernel_irqchip=split,memory-encryption=tdx,memory-backend=ram1
> > 
> > Changelog
> > --
> > v3:
> >   - Added locking protection when calling
> > invalidate_page_range/fallocate callbacks.
> >   - Changed memslot structure to keep use useraddr for shared memory.
> >   - Re-organized F_SEAL_INACCESSIBLE and MEMFD_OPS.
> >   - Added MFD_INACCESSIBLE flag to force F_SEAL_INACCESSIBLE.
> >   - Commit message improvement.
> >   - Many small fixes for comments from the last version.
> 
> Can you rebase on top of kvm/queue and send a new version?  There's a massive
> overhaul of KVM's memslots code that's queued for 5.17, and the KVM core 
> changes
> in this series conflict mightily.

Sure, will do the rebase and send a new version.

> 
> It's ok if the private memslot support isn't tested exactly as-is, it's not 
> like
> any of us reviewers can test it anyways, but I would like to be able to apply
> cleanly and verify that the series doesn't break existing functionality.

Good, it will ease me if that is acceptable (e.g. test on the relative
new TDX codebase but send out the patch on latest kvm/queue which is not
verified for the new function). This gets rid of the 'chicken and egg'
dependency between this series and TDX patchset.

> 
> This version also appears to be based on an internal development branch, e.g. 
> patch
> 12/15 has some bits from the TDX series.

Right, it's based on latest TDX code 
https://github.com/intel/tdx/tree/kvm-upstream.
I did this because this is the only way I can test the code. 

Thanks,
Chao
> 
> @@ -336,6 +348,7 @@ struct kvm_tdx_exit {
>  #define KVM_EXIT_X86_BUS_LOCK 33
>  #define KVM_EXIT_XEN  34
>  #define KVM_EXIT_RISCV_SBI35
> +#define KVM_EXIT_MEMORY_ERROR 36
>  #define KVM_EXIT_TDX  50   /* dump number to avoid conflict. */
> 
>  /* For KVM_EXIT_INTERNAL_ERROR */
> @@ -554,6 +567,8 @@ struct kvm_run {
> unsigned long args[6];
> unsigned long ret[2];
> } riscv_sbi;
> +   /* KVM_EXIT_MEMORY_ERROR */
> +   struct kvm_memory_exit mem;
> /* KVM_EXIT_TDX_VMCALL */
> struct kvm_tdx_exit tdx;
> /* Fix the size of the union. */



[PATCH v2 2/3] ui: Revert: "fix incorrect pointer position on highdpi with gtk"

2021-12-21 Thread Alexander Orzechowski
This reverts commit f14aab420c58b57e07189d6d9e6d3fbfab4761a6.

This commit was originally tested on gtk/gl which corrected behavior
there. Turns out, the OpenGL texture representing the virtual console
was being rendered in the incorrect place and not that the cursor
was incorrectly being handled.

Signed-off-by: Alexander Orzechowski 
---
 ui/gtk.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 824334ff3d..b7f296fac7 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -836,7 +836,7 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 int x, y;
 int mx, my;
 int fbh, fbw;
-int ww, wh, ws;
+int ww, wh;
 
 if (!vc->gfx.ds) {
 return TRUE;
@@ -847,8 +847,6 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 
 ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
 wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
-ws = gdk_window_get_scale_factor(
-gtk_widget_get_window(vc->gfx.drawing_area));
 
 mx = my = 0;
 if (ww > fbw) {
@@ -858,8 +856,8 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 my = (wh - fbh) / 2;
 }
 
-x = (motion->x - mx) / vc->gfx.scale_x * ws;
-y = (motion->y - my) / vc->gfx.scale_y * ws;
+x = (motion->x - mx) / vc->gfx.scale_x;
+y = (motion->y - my) / vc->gfx.scale_y;
 
 if (qemu_input_is_absolute()) {
 if (x < 0 || y < 0 ||
-- 
2.34.1




[PATCH v2 1/3] ui: Use allocated size instead of window size

2021-12-21 Thread Alexander Orzechowski
In these cases, we only care about the size of the virtual console
itself. Previously, these calculations were made using the size of
the entire window, which would include the size of the virtual console
plus all the ui elements around it.

Signed-off-by: Alexander Orzechowski 
Reviewed-by: Marc-André Lureau 
---
 ui/gtk.c | 26 ++
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 428f02f2df..824334ff3d 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -340,8 +340,8 @@ static void gd_update_full_redraw(VirtualConsole *vc)
 {
 GtkWidget *area = vc->gfx.drawing_area;
 int ww, wh;
-ww = gdk_window_get_width(gtk_widget_get_window(area));
-wh = gdk_window_get_height(gtk_widget_get_window(area));
+ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
 #if defined(CONFIG_OPENGL)
 if (vc->gfx.gls && gtk_use_gl_area) {
 gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
@@ -387,7 +387,6 @@ static void gd_update(DisplayChangeListener *dcl,
   int x, int y, int w, int h)
 {
 VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-GdkWindow *win;
 int x1, x2, y1, y2;
 int mx, my;
 int fbw, fbh;
@@ -414,12 +413,8 @@ static void gd_update(DisplayChangeListener *dcl,
 fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
 fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
 
-win = gtk_widget_get_window(vc->gfx.drawing_area);
-if (!win) {
-return;
-}
-ww = gdk_window_get_width(win);
-wh = gdk_window_get_height(win);
+ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
 
 mx = my = 0;
 if (ww > fbw) {
@@ -788,8 +783,8 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t 
*cr, void *opaque)
 fbw = surface_width(vc->gfx.ds);
 fbh = surface_height(vc->gfx.ds);
 
-ww = gdk_window_get_width(gtk_widget_get_window(widget));
-wh = gdk_window_get_height(gtk_widget_get_window(widget));
+ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area); 
 
 if (s->full_screen) {
 vc->gfx.scale_x = (double)ww / fbw;
@@ -838,7 +833,6 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 {
 VirtualConsole *vc = opaque;
 GtkDisplayState *s = vc->s;
-GdkWindow *window;
 int x, y;
 int mx, my;
 int fbh, fbw;
@@ -851,10 +845,10 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
 fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
 
-window = gtk_widget_get_window(vc->gfx.drawing_area);
-ww = gdk_window_get_width(window);
-wh = gdk_window_get_height(window);
-ws = gdk_window_get_scale_factor(window);
+ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
+ws = gdk_window_get_scale_factor(
+gtk_widget_get_window(vc->gfx.drawing_area));
 
 mx = my = 0;
 if (ww > fbw) {
-- 
2.34.1




[PATCH v2 3/3] ui: Fix gtk/gl when the scaled virtual console does not fit the window

2021-12-21 Thread Alexander Orzechowski
gtk/gl was incorrectly always rendering as if the 'Zoom to Fit' was
always checked even if it wasn't. This is now using logic closer
to what is being used for the existing cairo code paths.

Signed-off-by: Alexander Orzechowski 
---
 ui/gtk-gl-area.c | 34 +-
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 01e4e74ee3..f4f2dac882 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -41,16 +41,40 @@ void gd_gl_area_draw(VirtualConsole *vc)
 #ifdef CONFIG_GBM
 QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 #endif
+GtkDisplayState *s = vc->s;
 int ww, wh, ws, y1, y2;
+int mx, my;
+int fbh, fbw;
 
 if (!vc->gfx.gls) {
 return;
 }
 
 gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
+
+fbw = surface_width(vc->gfx.ds);
+fbh = surface_height(vc->gfx.ds);
+
 ws = 
gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area));
-ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws;
-wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws;
+ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
+
+if (s->full_screen) {
+vc->gfx.scale_x = (double)ww / fbw;
+vc->gfx.scale_y = (double)wh / fbh;
+} else if (s->free_scale) {
+double sx, sy;
+
+sx = (double)ww / fbw;
+sy = (double)wh / fbh;
+
+vc->gfx.scale_x = vc->gfx.scale_y = MIN(sx, sy);
+}
+
+fbw *= vc->gfx.scale_x * ws;
+fbh *= vc->gfx.scale_y * ws;
+mx = (ww * ws - fbw) / 2;
+my = (wh * ws - fbh) / 2;
 
 if (vc->gfx.scanout_mode) {
 if (!vc->gfx.guest_fb.framebuffer) {
@@ -70,11 +94,11 @@ void gd_gl_area_draw(VirtualConsole *vc)
 glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
 /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
 
-glViewport(0, 0, ww, wh);
+glViewport(mx, my, fbw, fbh);
 y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
 y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
 glBlitFramebuffer(0, y1, vc->gfx.w, y2,
-  0, 0, ww, wh,
+  mx, my, fbw + mx, fbh + my,
   GL_COLOR_BUFFER_BIT, GL_NEAREST);
 #ifdef CONFIG_GBM
 if (dmabuf) {
@@ -98,7 +122,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
 }
 gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
 
-surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
+glViewport(mx, my, fbw, fbh);
 surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
 }
 
-- 
2.34.1




[PATCH v2 0/3] UI fixups

2021-12-21 Thread Alexander Orzechowski
Some UI fixups including one revert.

I have some things that I want to have a discussion about. Fullscreen mode
will always distort the virtual console. Is this behavior we really want? If we
get rid of this, we can combine scale_x and scale_y into a single variable
and simplify things a little bit.

Also just from looking around a little bit in ui/gtk-egl.c the code
seems super broken regarding the virtual console rendering in the correct place.
I'm unable to test those code paths so I haven't touched it for now.

Changes in v2:
 - Dropped patch 2, I couldn't figure out what to colour the bike shed
 - Fixed incorrect rendering when gtk/gl is using scanout_mode

Alexander Orzechowski (3):
  ui: Use allocated size instead of window size
  ui: Revert: "fix incorrect pointer position on highdpi with gtk"
  ui: Fix gtk/gl when the scaled virtual console does not fit the window

 ui/gtk-gl-area.c | 34 +-
 ui/gtk.c | 30 +++---
 2 files changed, 40 insertions(+), 24 deletions(-)

-- 
2.34.1




Re: [PATCH] pci: Skip power-off reset when pending unplug

2021-12-21 Thread Michael S. Tsirkin
On Tue, Dec 21, 2021 at 09:36:56AM -0700, Alex Williamson wrote:
> On Mon, 20 Dec 2021 18:03:56 -0500
> "Michael S. Tsirkin"  wrote:
> 
> > On Mon, Dec 20, 2021 at 11:26:59AM -0700, Alex Williamson wrote:
> > > The below referenced commit introduced a change where devices under a
> > > root port slot are reset in response to removing power to the slot.
> > > This improves emulation relative to bare metal when the slot is powered
> > > off, but introduces an unnecessary step when devices under that slot
> > > are slated for removal.
> > > 
> > > In the case of an assigned device, there are mandatory delays
> > > associated with many device reset mechanisms which can stall the hot
> > > unplug operation.  Also, in cases where the unplug request is triggered
> > > via a release operation of the host driver, internal device locking in
> > > the host kernel may result in a failure of the device reset mechanism,
> > > which generates unnecessary log warnings.
> > > 
> > > Skip the reset for devices that are slated for unplug.
> > > 
> > > Cc: qemu-sta...@nongnu.org
> > > Fixes: d5daff7d3126 ("pcie: implement slot power control for pcie root 
> > > ports")
> > > Signed-off-by: Alex Williamson   
> > 
> > I am not sure this is safe. IIUC pending_deleted_event
> > is normally set after host admin requested device removal,
> > while the reset could be triggered by guest for its own reasons
> > such as suspend or driver reload.
> 
> Right, the case where I mention that we get the warning looks exactly
> like the admin doing a device eject, it calls qdev_unplug().  I'm not
> trying to prevent arbitrary guest resets of the device, in fact there
> are cases where the guest really should be able to reset the device,
> nested assignment in addition to the cases you mention.  Gerd noted
> that this was an unintended side effect of the referenced patch to
> reset device that are imminently being removed.
> 
> > Looking at this some more, I am not sure I understand the
> > issue completely.
> > We have:
> > 
> > if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
> > (val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF &&
> > (!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
> > (old_slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
> > pcie_cap_slot_do_unplug(dev);
> > }
> > pcie_cap_update_power(dev);
> > 
> > so device unplug triggers first, reset follows and by that time
> > there should be no devices under the bus, if there are then
> > it's because guest did not clear the power indicator.
> 
> Note that the unplug only triggers here if the Power Indicator Control
> is OFF, I see writes to SLTCTL in the following order:
> 
>  01f1 - > 02f1 -> 06f1 -> 07f1
> 
> So PIC changes to BLINK, then PCC changes the slot to OFF (this
> triggers the reset), then PIC changes to OFF triggering the unplug.
> 
> The unnecessary reset that occurs here is universal.  Should the unplug
> be occurring when:
> 
>   (val & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_ON
> 
> ?

well blinking generally means "do not remove yet".

> > So I am not sure how to fix the assignment issues as I'm not sure how do
> > they trigger, but here is a wild idea: maybe it should support an API
> > for starting reset asynchronously, then if the following access is
> > trying to reset again that second reset can just be skipped, while any
> > other access will stall.
> 
> As above, there's not a concurrency problem, so I don't see how an
> async API buys us anything.

Well unplug resets the device again, right? Why is that reset not
problematic and this one is?

>  It seems the ordering of the slot power
> induced reset versus device unplug is not as you expected.  Can we fix
> that?  Thanks,
> 
> Alex

Oh I means on the PIC write. That triggers the unplug without triggering
a reset. I was under the impression you are saying the same guest
write triggers both reset and unplug.
Since in this case it's two writes, I don't see how we
can tie ourselves to guest doing things in a specific order.
It can always change the order of things.


> 
> > > ---
> > >  hw/pci/pci.c |2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > > index e5993c1ef52b..f594da410797 100644
> > > --- a/hw/pci/pci.c
> > > +++ b/hw/pci/pci.c
> > > @@ -2869,7 +2869,7 @@ void pci_set_power(PCIDevice *d, bool state)
> > >  memory_region_set_enabled(>bus_master_enable_region,
> > >(pci_get_word(d->config + PCI_COMMAND)
> > > & PCI_COMMAND_MASTER) && d->has_power);
> > > -if (!d->has_power) {
> > > +if (!d->has_power && !d->qdev.pending_deleted_event) {
> > >  pci_device_reset(d);
> > >  }
> > >  }
> > >   
> > 




Re: [RFC v2 01/12] target/ppc: powerpc_excp: Set alternate SRRs directly

2021-12-21 Thread Richard Henderson

On 12/20/21 10:18 AM, Fabiano Rosas wrote:

There are currently only two interrupts that use alternate SRRs, so
let them write to them directly during the setup code.

No functional change intented.

Signed-off-by: Fabiano Rosas
---
  target/ppc/excp_helper.c | 23 ---
  1 file changed, 8 insertions(+), 15 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 3/3] linux-user: netlink: update IFLA_BRPORT entries

2021-12-21 Thread Richard Henderson

On 12/19/21 7:45 AM, Laurent Vivier wrote:

add IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT and IFLA_BRPORT_MCAST_EHT_HOSTS_CNT

   # QEMU_LOG=unimp ip a
   Unknown QEMU_IFLA_BRPORT type 37
   Unknown QEMU_IFLA_BRPORT type 38

Signed-off-by: Laurent Vivier
---
  linux-user/fd-trans.c | 4 
  1 file changed, 4 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 2/3] linux-user: netlink: Add IFLA_VFINFO_LIST

2021-12-21 Thread Richard Henderson

On 12/19/21 7:45 AM, Laurent Vivier wrote:

   # QEMU_LOG=unimp ip a
   Unknown host QEMU_IFLA type: 22

Signed-off-by: Laurent Vivier
---
  linux-user/fd-trans.c | 174 ++
  1 file changed, 174 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/3] linux-user: netlink: update IFLA entries

2021-12-21 Thread Richard Henderson

On 12/19/21 7:45 AM, Laurent Vivier wrote:

Add IFLA_PHYS_PORT_ID, IFLA_PARENT_DEV_NAME, IFLA_PARENT_DEV_BUS_NAME

   # QEMU_LOG=unimp ip a
   Unknown host QEMU_IFLA type: 56
   Unknown host QEMU_IFLA type: 57
   Unknown host QEMU_IFLA type: 34

Signed-off-by: Laurent Vivier 
---
  linux-user/fd-trans.c | 6 ++
  1 file changed, 6 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 5/5] dma: Let ld*_pci_dma() propagate MemTxResult

2021-12-21 Thread Richard Henderson

On 12/18/21 7:10 AM, Philippe Mathieu-Daudé wrote:

ld*_dma() returns a MemTxResult type. Do not discard
it, return it to the caller.

Update the few callers.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/pci/pci.h | 17 -
  hw/audio/intel-hda.c |  2 +-
  hw/net/eepro100.c| 25 ++---
  hw/net/tulip.c   | 16 
  hw/scsi/megasas.c| 21 -
  hw/scsi/mptsas.c | 16 +++-
  hw/scsi/vmw_pvscsi.c | 16 ++--
  7 files changed, 60 insertions(+), 53 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c90cecc85c0..5b36334a28a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -850,15 +850,14 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, 
dma_addr_t addr,
DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
  }
  
-#define PCI_DMA_DEFINE_LDST(_l, _s, _bits)  \

-static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev,  \
-   dma_addr_t addr, \
-   MemTxAttrs attrs) \
-{   \
-uint##_bits##_t val; \
-ld##_l##_dma(pci_get_address_space(dev), addr, , attrs); \
-return val; \
-}   \
+#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
+static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \
+   dma_addr_t addr, \
+   uint##_bits##_t *val, \
+   MemTxAttrs attrs) \
+{ \
+return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \
+} \
  static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \
 dma_addr_t addr, \
 uint##_bits##_t val, \
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index e34b7ab0e92..2b55d521503 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -335,7 +335,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
  
  rp = (d->corb_rp + 1) & 0xff;

  addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
-verb = ldl_le_pci_dma(>pci, addr + 4 * rp, MEMTXATTRS_UNSPECIFIED);
+ldl_le_pci_dma(>pci, addr + 4 * rp, , MEMTXATTRS_UNSPECIFIED);
  d->corb_rp = rp;
  
  dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb);

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index eb82e9cb118..679f52f80f1 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -769,18 +769,16 @@ static void tx_command(EEPRO100State *s)
  } else {
  /* Flexible mode. */
  uint8_t tbd_count = 0;
+uint32_t tx_buffer_address;
+uint16_t tx_buffer_size;
+uint16_t tx_buffer_el;
+
  if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) {
  /* Extended Flexible TCB. */
  for (; tbd_count < 2; tbd_count++) {
-uint32_t tx_buffer_address = ldl_le_pci_dma(>dev,
-tbd_address,
-attrs);
-uint16_t tx_buffer_size = lduw_le_pci_dma(>dev,
-  tbd_address + 4,
-  attrs);
-uint16_t tx_buffer_el = lduw_le_pci_dma(>dev,
-tbd_address + 6,
-attrs);
+ldl_le_pci_dma(>dev, tbd_address, _buffer_address, 
attrs);
+lduw_le_pci_dma(>dev, tbd_address + 4, _buffer_size, 
attrs);
+lduw_le_pci_dma(>dev, tbd_address + 6, _buffer_el, 
attrs);
  tbd_address += 8;
  TRACE(RXTX, logout
  ("TBD (extended flexible mode): buffer address 0x%08x, size 
0x%04x\n",
@@ -796,12 +794,9 @@ static void tx_command(EEPRO100State *s)
  }
  tbd_address = tbd_array;
  for (; tbd_count < s->tx.tbd_count; tbd_count++) {
-uint32_t tx_buffer_address = ldl_le_pci_dma(>dev, tbd_address,
-attrs);
-uint16_t tx_buffer_size = lduw_le_pci_dma(>dev, tbd_address + 4,
-  attrs);
-uint16_t tx_buffer_el = lduw_le_pci_dma(>dev, tbd_address + 6,
-attrs);
+ldl_le_pci_dma(>dev, tbd_address, _buffer_address, attrs);
+lduw_le_pci_dma(>dev, tbd_address + 4, _buffer_size, attrs);
+

Re: [PATCH 4/5] dma: Let st*_pci_dma() propagate MemTxResult

2021-12-21 Thread Richard Henderson

On 12/18/21 7:10 AM, Philippe Mathieu-Daudé wrote:

st*_dma() returns a MemTxResult type. Do not discard
it, return it to the caller.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 3/5] dma: Let ld*_pci_dma() take MemTxAttrs argument

2021-12-21 Thread Richard Henderson

On 12/18/21 7:10 AM, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling ld*_pci_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h |  6 +++---
  hw/audio/intel-hda.c |  2 +-
  hw/net/eepro100.c| 19 +--
  hw/net/tulip.c   | 18 ++
  hw/scsi/megasas.c| 16 ++--
  hw/scsi/mptsas.c | 10 ++
  hw/scsi/vmw_pvscsi.c |  3 ++-
  hw/usb/hcd-xhci.c|  1 +
  8 files changed, 46 insertions(+), 29 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 2/5] dma: Let st*_pci_dma() take MemTxAttrs argument

2021-12-21 Thread Richard Henderson

On 12/18/21 7:10 AM, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling st*_pci_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h | 11 ++-
  hw/audio/intel-hda.c | 10 ++
  hw/net/eepro100.c| 29 ++---
  hw/net/tulip.c   | 18 ++
  hw/scsi/megasas.c| 15 ++-
  hw/scsi/vmw_pvscsi.c |  3 ++-
  6 files changed, 52 insertions(+), 34 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 4/4] dma: Let ld*_dma() propagate MemTxResult

2021-12-21 Thread Richard Henderson

On 12/18/21 6:51 AM, Philippe Mathieu-Daudé wrote:

dma_memory_read() returns a MemTxResult type. Do not discard
it, return it to the caller.

Update the few callers.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h   |  6 --
  include/hw/ppc/spapr_vio.h |  6 +-
  include/sysemu/dma.h   | 25 -
  hw/intc/pnv_xive.c |  8 
  hw/usb/hcd-xhci.c  |  7 ---
  5 files changed, 29 insertions(+), 23 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/5] hw/scsi/megasas: Use uint32_t for reply queue head/tail values

2021-12-21 Thread Richard Henderson

On 12/18/21 7:10 AM, Philippe Mathieu-Daudé wrote:

While the reply queue values fit in 16-bit, they are accessed
as 32-bit:

   661:s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa);
   662:s->reply_queue_head %= MEGASAS_MAX_FRAMES;
   663:s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
   664:s->reply_queue_tail %= MEGASAS_MAX_FRAMES;

Having:

   41:#define MEGASAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */

In order to update the ld/st*_pci_dma() API to pass the address
of the value to access, it is simpler to have the head/tail declared
as 32-bit values. Replace the uint16_t by uint32_t, wasting 4 bytes in
the MegasasState structure.

Signed-off-by: Philippe Mathieu-Daudé
---
  hw/scsi/megasas.c| 4 ++--
  hw/scsi/trace-events | 8 
  2 files changed, 6 insertions(+), 6 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH 3/4] dma: Let st*_dma() propagate MemTxResult

2021-12-21 Thread Richard Henderson

On 12/18/21 6:51 AM, Philippe Mathieu-Daudé wrote:

dma_memory_write() returns a MemTxResult type. Do not discard
it, return it to the caller.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/sysemu/dma.h | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 2/4] dma: Let ld*_dma() take MemTxAttrs argument

2021-12-21 Thread Richard Henderson

On 12/18/21 6:51 AM, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling ld*_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h   |  3 ++-
  include/hw/ppc/spapr_vio.h |  3 ++-
  include/sysemu/dma.h   | 11 ++-
  hw/intc/pnv_xive.c |  7 ---
  hw/usb/hcd-xhci.c  |  6 +++---
  5 files changed, 17 insertions(+), 13 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/4] dma: Let st*_dma() take MemTxAttrs argument

2021-12-21 Thread Richard Henderson

On 12/18/21 6:51 AM, Philippe Mathieu-Daudé wrote:

Let devices specify transaction attributes when calling st*_dma().

Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/pci/pci.h   |  3 ++-
  include/hw/ppc/spapr_vio.h | 12 
  include/sysemu/dma.h   | 10 ++
  hw/nvram/fw_cfg.c  |  4 ++--
  4 files changed, 18 insertions(+), 11 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 00/30] tcg/loongarch64: New tcg backend

2021-12-21 Thread Richard Henderson

On 12/21/21 1:25 PM, Richard Henderson wrote:

Version 2: Dropped patch 31, the gitlab-ci change:

Found errors in your .gitlab-ci.yml:
'cross-loongarch64-system' job needs 'loongarch64-cross-container' job
but 'loongarch64-cross-container' is not in any previous stage
'cross-loongarch64-user' job needs 'loongarch64-cross-container' job
but 'loongarch64-cross-container' is not in any previous stage


r~


The following changes since commit 5316e12bb2b4408a1597b283ef4bb4794dd7b4f7:

   Merge tag 'dbus-pull-request' of https://gitlab.com/marcandre.lureau/qemu 
into staging (2021-12-21 08:00:26 -0800)

are available in the Git repository at:

   https://gitlab.com/rth7680/qemu.git tags/pull-loong-20211221-2

for you to fetch changes up to dfcf900ba67040ea9aa839aa38b33b4c091721d8:

   configure, meson.build: Mark support for loongarch64 hosts (2021-12-21 
13:17:06 -0800)


Initial commit of tcg/loongarch64


WANG Xuerui (30):
   elf: Add machine type value for LoongArch
   MAINTAINERS: Add tcg/loongarch64 entry with myself as maintainer
   tcg/loongarch64: Add the tcg-target.h file
   tcg/loongarch64: Add generated instruction opcodes and encoding helpers
   tcg/loongarch64: Add register names, allocation order and input/output 
sets
   tcg/loongarch64: Define the operand constraints
   tcg/loongarch64: Implement necessary relocation operations
   tcg/loongarch64: Implement the memory barrier op
   tcg/loongarch64: Implement tcg_out_mov and tcg_out_movi
   tcg/loongarch64: Implement goto_ptr
   tcg/loongarch64: Implement sign-/zero-extension ops
   tcg/loongarch64: Implement not/and/or/xor/nor/andc/orc ops
   tcg/loongarch64: Implement deposit/extract ops
   tcg/loongarch64: Implement bswap{16,32,64} ops
   tcg/loongarch64: Implement clz/ctz ops
   tcg/loongarch64: Implement shl/shr/sar/rotl/rotr ops
   tcg/loongarch64: Implement add/sub ops
   tcg/loongarch64: Implement mul/mulsh/muluh/div/divu/rem/remu ops
   tcg/loongarch64: Implement br/brcond ops
   tcg/loongarch64: Implement setcond ops
   tcg/loongarch64: Implement tcg_out_call
   tcg/loongarch64: Implement simple load/store ops
   tcg/loongarch64: Add softmmu load/store helpers, implement 
qemu_ld/qemu_st ops
   tcg/loongarch64: Implement tcg_target_qemu_prologue
   tcg/loongarch64: Implement exit_tb/goto_tb
   tcg/loongarch64: Implement tcg_target_init
   tcg/loongarch64: Register the JIT
   common-user: Add safe syscall handling for loongarch64 hosts
   linux-user: Implement CPU-specific signal handler for loongarch64 hosts
   configure, meson.build: Mark support for loongarch64 hosts

  configure   |5 +
  meson.build |2 +-
  include/elf.h   |2 +
  linux-user/host/loongarch64/host-signal.h   |   87 ++
  tcg/loongarch64/tcg-target-con-set.h|   31 +
  tcg/loongarch64/tcg-target-con-str.h|   28 +
  tcg/loongarch64/tcg-target.h|  180 +++
  tcg/loongarch64/tcg-insn-defs.c.inc |  979 +
  tcg/loongarch64/tcg-target.c.inc| 1677 +++
  MAINTAINERS |5 +
  common-user/host/loongarch64/safe-syscall.inc.S |   90 ++
  11 files changed, 3085 insertions(+), 1 deletion(-)
  create mode 100644 linux-user/host/loongarch64/host-signal.h
  create mode 100644 tcg/loongarch64/tcg-target-con-set.h
  create mode 100644 tcg/loongarch64/tcg-target-con-str.h
  create mode 100644 tcg/loongarch64/tcg-target.h
  create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc
  create mode 100644 tcg/loongarch64/tcg-target.c.inc
  create mode 100644 common-user/host/loongarch64/safe-syscall.inc.S


Applied, thanks.


r~




Re: powernv gitlab ci regression

2021-12-21 Thread Cédric Le Goater

Just rewrote the fore-mentioned patch using TCG ops. Here's some numbers 
running the tests on
my local machine:

- using current master:

  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (71.00 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (69.57 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (76.04 s)


  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (72.62 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (76.50 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (73.58 s)


- after my TCG Ops rewrite to count instructions:


  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (39.97 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (40.19 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (41.76 s)

  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (40.88 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (41.49 s)
  (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (42.04 s)


Also, there's a high possibility that the code I wrote is not optimized since 
I'm not well
versed with TCG ops/code. I expect that after a couple of reviews from Richard 
we might be able
to bring down those numbers even further.


This is behaving like 6.2. We should be fine (until we add more counters :)
  

I'll clean this up and send for review.

ok. We might have a last ppc PR in 2021.

Thanks a lot,

C.




Re: [PATCH] target/riscv: make H-extension non-experimental

2021-12-21 Thread Alistair Francis
On Wed, Dec 22, 2021 at 3:22 AM Vineet Gupta  wrote:
>
> H-ext v1.0 was ratified recently as part of Privileged Spec 1.12.
> So move it out of experimental.
>
> [1] https://wiki.riscv.org/display/TECH/Recently+Ratified+Extensions
>
> Signed-off-by: Vineet Gupta 

Thanks for the patch!

There is already a similar patch on the mailing list though.

Alistair

> ---
>  target/riscv/cpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 6ef3314bced8..a582179b1773 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -640,12 +640,12 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
>  DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
>
> -/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
>  DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
>  DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
>  DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
> -DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
> +DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, false),
> +/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
>  /* ePMP 0.9.3 */
>  DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
> --
> 2.30.2
>
>



Re: [PATCH 7/8] configure, meson: move config-poison.h to meson

2021-12-21 Thread Richard Henderson

On 12/21/21 3:05 AM, Paolo Bonzini wrote:

+genh += custom_target('config-poison.h',
+  input: [target_configs_h],
+  output: 'config-poison.h',
+  capture: true,
+  command: [find_program('scripts/make-config-poison.sh')] 
+
+   (target_configs_h.length() > 0 ? ['@INPUT@'] : 
[]))


Using length + @INPUT@ seems needlessly around the bush.
Perhaps better as

  [find_program...] + target_configs_h

Otherwise it looks ok.


r~



Re: powernv gitlab ci regression

2021-12-21 Thread Daniel Henrique Barboza




On 12/21/21 06:44, Daniel Henrique Barboza wrote:



On 12/21/21 05:20, Cédric Le Goater wrote:

On 12/21/21 03:37, Daniel Henrique Barboza wrote:

Hey,

On 12/20/21 18:35, Richard Henderson wrote:

Hi guys,

Somewhere within


Merge tag 'pull-ppc-20211217' of https://github.com/legoater/qemu into staging
ppc 7.0 queue:

* General cleanup for Mac machines (Peter)
* Fixes for FPU exceptions (Lucas)
* Support for new ISA31 instructions (Matheus)
* Fixes for ivshmem (Daniel)
* Cleanups for PowerNV PHB (Christophe and Cedric)
* Updates of PowerNV and pSeries documentation (Leonardo and Daniel)
* Fixes for PowerNV (Daniel)
* Large cleanup of FPU implementation (Richard)
* Removal of SoftTLBs support for PPC74x CPUs (Fabiano)
* Fixes for exception models in MPCx and 60x CPUs (Fabiano)
* Removal of 401/403 CPUs (Cedric)
* Deprecation of taihu machine (Thomas)
* Large rework of PPC405 machine (Cedric)
* Fixes for VSX instructions (Victor and Matheus)
* Fix for e6500 CPU (Fabiano)
* Initial support for PMU (Daniel)


is something that has caused a timeout regression in avocado-system-centos:


 (047/171) 
tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8:  
INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred: Timeout 
reached\nOriginal status: ERROR\n{'name': 
'047-tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8', 
'logdir': 
'/builds/qemu-project/qemu/build/tests/results/job-2021-12-17T19.23-... (90.46 
s)
 (048/171) 
tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9:  
INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred: Timeout 
reached\nOriginal status: ERROR\n{'name': 
'048-tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9', 
'logdir': 
'/builds/qemu-project/qemu/build/tests/results/job-2021-12-17T19.23-... (90.55 
s)


See e.g. https://gitlab.com/qemu-project/qemu/-/jobs/1898304074


Thanks for letting us know. I bisected it and the culprit is this patch:


commit 4db3907a40a087e2cc1839d19a3642539d36610b
Author: Daniel Henrique Barboza 
Date:   Fri Dec 17 17:57:18 2021 +0100

 target/ppc: enable PMU instruction count


This is a patch where I added instruction count in the ppc64 PMU. After this 
patch the
performance of these 2 tests are degraded to the point where we're hitting 
timeouts in
gitlab (didn't hit timeouts in my machine but the performance is noticeable 
worse).

I'll need to see the serial console of the VM booting up to evaluate if there's 
some kernel
module during boot time that is using the PMU and causing the delay. I'll also 
take a look
into improving the performance as well (e.g. using more TCG code and avoid 
calling helpers).\


Just rewrote the fore-mentioned patch using TCG ops. Here's some numbers 
running the tests on
my local machine:

- using current master:

 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (71.00 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (69.57 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (76.04 s)


 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (72.62 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (76.50 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (73.58 s)


- after my TCG Ops rewrite to count instructions:


 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (39.97 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (40.19 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (41.76 s)

 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (40.88 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (41.49 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (42.04 s)


Also, there's a high possibility that the code I wrote is not optimized since 
I'm not well
versed with TCG ops/code. I expect that after a couple of reviews from Richard 
we might be able
to bring down those numbers even further.


I'll clean this up and send for review.


Thanks,


Daniel





Run with :

   build/tests/venv/bin/avocado --show=app,console run -t machine:powernv9  
build/tests/avocado/boot_linux_console.py

* 6.2

...
console: [    1.559904] PCI: CLS 0 bytes, default 128
/console: [    8.830245] Initialise system trusted keyrings
console: [    8.832347] Key type blacklist registered
console: [    8.834558] workingset: timestamp_bits=54 max_order=14 
bucket_order=0
console: [    9.073051] integrity: Platform Keyring initialized
console: [    9.073586] Key type asymmetric registered
console: [    9.074025] Asymmetric key parser 'x509' registered
console: [    9.075359] Block layer SCSI generic (bsg) driver version 

[PATCH v2 00/30] tcg/loongarch64: New tcg backend

2021-12-21 Thread Richard Henderson
Version 2: Dropped patch 31, the gitlab-ci change:

Found errors in your .gitlab-ci.yml:
'cross-loongarch64-system' job needs 'loongarch64-cross-container' job
but 'loongarch64-cross-container' is not in any previous stage
'cross-loongarch64-user' job needs 'loongarch64-cross-container' job
but 'loongarch64-cross-container' is not in any previous stage


r~


The following changes since commit 5316e12bb2b4408a1597b283ef4bb4794dd7b4f7:

  Merge tag 'dbus-pull-request' of https://gitlab.com/marcandre.lureau/qemu 
into staging (2021-12-21 08:00:26 -0800)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-loong-20211221-2

for you to fetch changes up to dfcf900ba67040ea9aa839aa38b33b4c091721d8:

  configure, meson.build: Mark support for loongarch64 hosts (2021-12-21 
13:17:06 -0800)


Initial commit of tcg/loongarch64


WANG Xuerui (30):
  elf: Add machine type value for LoongArch
  MAINTAINERS: Add tcg/loongarch64 entry with myself as maintainer
  tcg/loongarch64: Add the tcg-target.h file
  tcg/loongarch64: Add generated instruction opcodes and encoding helpers
  tcg/loongarch64: Add register names, allocation order and input/output 
sets
  tcg/loongarch64: Define the operand constraints
  tcg/loongarch64: Implement necessary relocation operations
  tcg/loongarch64: Implement the memory barrier op
  tcg/loongarch64: Implement tcg_out_mov and tcg_out_movi
  tcg/loongarch64: Implement goto_ptr
  tcg/loongarch64: Implement sign-/zero-extension ops
  tcg/loongarch64: Implement not/and/or/xor/nor/andc/orc ops
  tcg/loongarch64: Implement deposit/extract ops
  tcg/loongarch64: Implement bswap{16,32,64} ops
  tcg/loongarch64: Implement clz/ctz ops
  tcg/loongarch64: Implement shl/shr/sar/rotl/rotr ops
  tcg/loongarch64: Implement add/sub ops
  tcg/loongarch64: Implement mul/mulsh/muluh/div/divu/rem/remu ops
  tcg/loongarch64: Implement br/brcond ops
  tcg/loongarch64: Implement setcond ops
  tcg/loongarch64: Implement tcg_out_call
  tcg/loongarch64: Implement simple load/store ops
  tcg/loongarch64: Add softmmu load/store helpers, implement 
qemu_ld/qemu_st ops
  tcg/loongarch64: Implement tcg_target_qemu_prologue
  tcg/loongarch64: Implement exit_tb/goto_tb
  tcg/loongarch64: Implement tcg_target_init
  tcg/loongarch64: Register the JIT
  common-user: Add safe syscall handling for loongarch64 hosts
  linux-user: Implement CPU-specific signal handler for loongarch64 hosts
  configure, meson.build: Mark support for loongarch64 hosts

 configure   |5 +
 meson.build |2 +-
 include/elf.h   |2 +
 linux-user/host/loongarch64/host-signal.h   |   87 ++
 tcg/loongarch64/tcg-target-con-set.h|   31 +
 tcg/loongarch64/tcg-target-con-str.h|   28 +
 tcg/loongarch64/tcg-target.h|  180 +++
 tcg/loongarch64/tcg-insn-defs.c.inc |  979 +
 tcg/loongarch64/tcg-target.c.inc| 1677 +++
 MAINTAINERS |5 +
 common-user/host/loongarch64/safe-syscall.inc.S |   90 ++
 11 files changed, 3085 insertions(+), 1 deletion(-)
 create mode 100644 linux-user/host/loongarch64/host-signal.h
 create mode 100644 tcg/loongarch64/tcg-target-con-set.h
 create mode 100644 tcg/loongarch64/tcg-target-con-str.h
 create mode 100644 tcg/loongarch64/tcg-target.h
 create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc
 create mode 100644 tcg/loongarch64/tcg-target.c.inc
 create mode 100644 common-user/host/loongarch64/safe-syscall.inc.S



Re: [PATCH 3/8] configure, makefile: remove traces of really old files

2021-12-21 Thread Richard Henderson

On 12/21/21 3:05 AM, Paolo Bonzini wrote:

These files have been removed for more than year in the best
case, or for more than ten years for some really old TCG files.
Remove any traces of it.

Signed-off-by: Paolo Bonzini
---
  Makefile  | 11 ---
  configure |  9 -
  2 files changed, 4 insertions(+), 16 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH 2/8] configure: do not set bsd_user/linux_user early

2021-12-21 Thread Richard Henderson

On 12/21/21 3:05 AM, Paolo Bonzini wrote:

Similar to other optional features, leave the variables empty and compute
the actual value later.  Use the existence of include or source directories
to detect whether an OS or CPU supports respectively bsd-user and linux-user.

For now, BSD user-mode emulation is buildable even on TCI-only
architectures.  This probably will change once safe signals are
brought over from linux-user.

Signed-off-by: Paolo Bonzini
---
  configure | 28 +---
  1 file changed, 17 insertions(+), 11 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/8] configure: simplify creation of plugin symbol list

2021-12-21 Thread Richard Henderson

On 12/21/21 3:05 AM, Paolo Bonzini wrote:

--dynamic-list is present on all supported ELF (not Windows or Darwin)
platforms, since it dates back to 2006; -exported_symbols_list is
likewise present on all supported versions of macOS.  Do not bother
doing a functional test in configure.

Remove the file creation from configure as well: for Darwin, move the
the creation of the Darwin-formatted symbols to meson; for ELF, use the
file in the source path directly and switch from -Wl, to -Xlinker to
not break weird paths that include a comma.

Signed-off-by: Paolo Bonzini
---
  configure   | 80 -
  plugins/meson.build | 11 +--
  2 files changed, 8 insertions(+), 83 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/3] meson: reuse common_user_inc when building files specific to user-mode emulators

2021-12-21 Thread Richard Henderson

On 12/21/21 8:32 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzini
---
  meson.build | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 2/3] user: move common-user includes to a subdirectory of {bsd,linux}-user/

2021-12-21 Thread Richard Henderson

On 12/21/21 8:32 AM, Paolo Bonzini wrote:

Avoid polluting the compilation of common-user/ with local include files;
making an include file available to common-user/ should be a deliberate
decision in order to keep a clear interface that can be used by both
bsd-user/ and linux-user/.

Signed-off-by: Paolo Bonzini
---
  bsd-user/{ => include}/special-errno.h  | 0
  bsd-user/meson.build| 2 +-
  linux-user/{ => include}/host/aarch64/host-signal.h | 0
  linux-user/{ => include}/host/alpha/host-signal.h   | 0
  linux-user/{ => include}/host/arm/host-signal.h | 0
  linux-user/{ => include}/host/i386/host-signal.h| 0
  linux-user/{ => include}/host/mips/host-signal.h| 0
  linux-user/{ => include}/host/ppc/host-signal.h | 0
  linux-user/{ => include}/host/ppc64/host-signal.h   | 0
  linux-user/{ => include}/host/riscv/host-signal.h   | 0
  linux-user/{ => include}/host/s390/host-signal.h| 0
  linux-user/{ => include}/host/s390x/host-signal.h   | 0
  linux-user/{ => include}/host/sparc/host-signal.h   | 0
  linux-user/{ => include}/host/sparc64/host-signal.h | 0
  linux-user/{ => include}/host/x32/host-signal.h | 0
  linux-user/{ => include}/host/x86_64/host-signal.h  | 0
  linux-user/{ => include}/special-errno.h| 0
  linux-user/meson.build  | 4 ++--
  18 files changed, 3 insertions(+), 3 deletions(-)
  rename bsd-user/{ => include}/special-errno.h (100%)
  rename linux-user/{ => include}/host/aarch64/host-signal.h (100%)
  rename linux-user/{ => include}/host/alpha/host-signal.h (100%)
  rename linux-user/{ => include}/host/arm/host-signal.h (100%)
  rename linux-user/{ => include}/host/i386/host-signal.h (100%)
  rename linux-user/{ => include}/host/mips/host-signal.h (100%)
  rename linux-user/{ => include}/host/ppc/host-signal.h (100%)
  rename linux-user/{ => include}/host/ppc64/host-signal.h (100%)
  rename linux-user/{ => include}/host/riscv/host-signal.h (100%)
  rename linux-user/{ => include}/host/s390/host-signal.h (100%)
  rename linux-user/{ => include}/host/s390x/host-signal.h (100%)
  rename linux-user/{ => include}/host/sparc/host-signal.h (100%)
  rename linux-user/{ => include}/host/sparc64/host-signal.h (100%)
  rename linux-user/{ => include}/host/x32/host-signal.h (100%)
  rename linux-user/{ => include}/host/x86_64/host-signal.h (100%)
  rename linux-user/{ => include}/special-errno.h (100%)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 3/3] meson: cleanup common-user/ build

2021-12-21 Thread Richard Henderson

On 12/21/21 8:33 AM, Paolo Bonzini wrote:

Do not go through a static_library, which is only necessary in order to reuse
some source files between emulators and tests.


That's not true, is it.  Anyway, you're moving the file to a different static_library.  I 
though I had tried this myself, but I don't remember the details now.


Tested-by: Richard Henderson 
Reviewed-by: Richard Henderson 


r~



Re: [PATCH 2/3] user: move common-user includes to a subdirectory of {bsd,linux}-user/

2021-12-21 Thread Richard Henderson

On 12/21/21 11:56 AM, Richard Henderson wrote:

On 12/21/21 8:32 AM, Paolo Bonzini wrote:

Avoid polluting the compilation of common-user/ with local include files;
making an include file available to common-user/ should be a deliberate
decision in order to keep a clear interface that can be used by both
bsd-user/ and linux-user/.


The reason that I did not do this before is that very shortly we're going to have 
bsd-user/host/arch/host-signal.h too.


If we combine them into a top-level include like this, then we have to add host-specific 
ifdefs.  IMO it is cleaner to leave them separate.


If you really really want to move them out of -user/include/host, then the only other 
thing I can suggest is include/host///.


Bah. Nevermind, I now see it's not top-level.


r~




Re: [PATCH 2/3] user: move common-user includes to a subdirectory of {bsd,linux}-user/

2021-12-21 Thread Richard Henderson

On 12/21/21 8:32 AM, Paolo Bonzini wrote:

Avoid polluting the compilation of common-user/ with local include files;
making an include file available to common-user/ should be a deliberate
decision in order to keep a clear interface that can be used by both
bsd-user/ and linux-user/.


The reason that I did not do this before is that very shortly we're going to have 
bsd-user/host/arch/host-signal.h too.


If we combine them into a top-level include like this, then we have to add host-specific 
ifdefs.  IMO it is cleaner to leave them separate.


If you really really want to move them out of -user/include/host, then the only other 
thing I can suggest is include/host///.



r~



[PATCH 1/3] scripts/qapi/commands: gen_commands(): add add_trace_points argument

2021-12-21 Thread Vladimir Sementsov-Ogievskiy
Add possibility to generate trace points for each qmp command.

We should generate both trace points and trace-events file, for further
trace point code generation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 scripts/qapi/commands.py | 84 ++--
 1 file changed, 73 insertions(+), 11 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 21001bbd6b..e62f1a4125 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -53,7 +53,8 @@ def gen_command_decl(name: str,
 def gen_call(name: str,
  arg_type: Optional[QAPISchemaObjectType],
  boxed: bool,
- ret_type: Optional[QAPISchemaType]) -> str:
+ ret_type: Optional[QAPISchemaType],
+ add_trace_points: bool) -> str:
 ret = ''
 
 argstr = ''
@@ -71,21 +72,65 @@ def gen_call(name: str,
 if ret_type:
 lhs = 'retval = '
 
-ret = mcgen('''
+qmp_name = f'qmpq_{c_name(name)}'
+upper = qmp_name.upper()
+
+if add_trace_points:
+ret += mcgen('''
+
+if (trace_event_get_state_backends(TRACE_%(upper)s)) {
+g_autoptr(GString) req_json = qobject_to_json(QOBJECT(args));
+trace_%(qmp_name)s("", req_json->str);
+}
+''',
+ upper=upper, qmp_name=qmp_name)
+
+ret += mcgen('''
 
 %(lhs)sqmp_%(c_name)s(%(args)s);
-error_propagate(errp, err);
 ''',
 c_name=c_name(name), args=argstr, lhs=lhs)
-if ret_type:
-ret += mcgen('''
+
+ret += mcgen('''
 if (err) {
+''')
+
+if add_trace_points:
+ret += mcgen('''
+trace_%(qmp_name)s("FAIL: ", error_get_pretty(err));
+''',
+ qmp_name=qmp_name)
+
+ret += mcgen('''
+error_propagate(errp, err);
 goto out;
 }
+''')
+
+if ret_type:
+ret += mcgen('''
 
 qmp_marshal_output_%(c_name)s(retval, ret, errp);
 ''',
  c_name=ret_type.c_name())
+
+if add_trace_points:
+if ret_type:
+ret += mcgen('''
+
+if (trace_event_get_state_backends(TRACE_%(upper)s)) {
+g_autoptr(GString) ret_json = qobject_to_json(*ret);
+trace_%(qmp_name)s("RET:", ret_json->str);
+}
+''',
+ upper=upper, qmp_name=qmp_name)
+else:
+ret += mcgen('''
+
+trace_%(qmp_name)s("SUCCESS", "");
+''',
+ qmp_name=qmp_name)
+
 return ret
 
 
@@ -122,10 +167,14 @@ def gen_marshal_decl(name: str) -> str:
  proto=build_marshal_proto(name))
 
 
+def gen_trace(name: str) -> str:
+return f'qmpq_{c_name(name)}(const char *tag, const char *json) "%s%s"\n'
+
 def gen_marshal(name: str,
 arg_type: Optional[QAPISchemaObjectType],
 boxed: bool,
-ret_type: Optional[QAPISchemaType]) -> str:
+ret_type: Optional[QAPISchemaType],
+add_trace_points: bool) -> str:
 have_args = boxed or (arg_type and not arg_type.is_empty())
 if have_args:
 assert arg_type is not None
@@ -180,7 +229,7 @@ def gen_marshal(name: str,
 }
 ''')
 
-ret += gen_call(name, arg_type, boxed, ret_type)
+ret += gen_call(name, arg_type, boxed, ret_type, add_trace_points)
 
 ret += mcgen('''
 
@@ -238,11 +287,12 @@ def gen_register_command(name: str,
 
 
 class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
-def __init__(self, prefix: str):
+def __init__(self, prefix: str, add_trace_points: bool):
 super().__init__(
 prefix, 'qapi-commands',
 ' * Schema-defined QAPI/QMP commands', None, __doc__)
 self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {}
+self.add_trace_points = add_trace_points
 
 def _begin_user_module(self, name: str) -> None:
 self._visited_ret_types[self._genc] = set()
@@ -261,6 +311,15 @@ def _begin_user_module(self, name: str) -> None:
 
 ''',
  commands=commands, visit=visit))
+
+if self.add_trace_points and c_name(commands) != 'qapi_commands':
+self._genc.add(mcgen('''
+#include "trace/trace-qapi.h"
+#include "qapi/qmp/qjson.h"
+#include "trace/trace-%(nm)s_trace_events.h"
+''',
+ nm=c_name(commands)))
+
 self._genh.add(mcgen('''
 #include "%(types)s.h"
 
@@ -322,7 +381,9 @@ def visit_command(self,
 with ifcontext(ifcond, self._genh, self._genc):
 self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
 self._genh.add(gen_marshal_decl(name))
-self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
+self._genc.add(gen_marshal(name, arg_type, boxed, ret_type,
+   self.add_trace_points))
+self._gent.add(gen_trace(name))
 with self._temp_module('./init'):
 with ifcontext(ifcond, self._genh, 

[PATCH RFC 0/3] trace qmp commands

2021-12-21 Thread Vladimir Sementsov-Ogievskiy
Hi all!

This series aims to add trace points for each qmp command with help of
qapi code generator.

That's a replacement for my
"[PATCH 0/5] trace: inroduce qmp: trace namespace"
Supersedes: <20210923195451.714796-1-vsement...@virtuozzo.com>


There are some problems, so that's an RFC.

1. Main problem is that I failed to teach meson how to build trace
points for generated trace-events files. I can build it, but.. See
commit 03 for the description.

2. I added --add-trace-points option to qapi-gen, to generate trace
points optionally. Probably that would be better to do it without an
option, but I failed to fix build for qmp commands in qga and in tests

Vladimir Sementsov-Ogievskiy (3):
  scripts/qapi/commands: gen_commands(): add add_trace_points argument
  scripts/qapi-gen.py: add --add-trace-points option
  meson: generate trace points for qmp commands

 meson.build  |  1 +
 qapi/meson.build |  4 +-
 scripts/qapi/commands.py | 84 ++--
 scripts/qapi/gen.py  | 13 +--
 scripts/qapi/main.py | 10 +++--
 trace/meson.build| 10 +++--
 6 files changed, 101 insertions(+), 21 deletions(-)

-- 
2.31.1




[PATCH 3/3] meson: generate trace points for qmp commands

2021-12-21 Thread Vladimir Sementsov-Ogievskiy
I need help with this thing. Now it works like this:

make -j9
ninja: error: 
'/work/src/qemu/up/up-trace-qmp-commands/build/qapi/qapi-commands-authz.trace-events',
 needed by 'trace/trace-events-all', missing and no known rule to make it
make[1]: *** [Makefile:162: run-ninja] Error 1
make[1]: Leaving directory '/work/src/qemu/up/up-trace-qmp-commands/build'
make: *** [GNUmakefile:11: all] Error 2

OK, let's try to make it by hand:

make qapi/qapi-commands-authz.trace-events
changing dir to build for make "qapi/qapi-commands-authz.trace-events"...
make[1]: Entering directory '/work/src/qemu/up/up-trace-qmp-commands/build'
  GIT ui/keycodemapdb meson tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc capstone slirp
[1/1] Generating shared QAPI source files with a custom command
make[1]: Leaving directory '/work/src/qemu/up/up-trace-qmp-commands/build'

It works! So meson doesn't understand that absolute path is the same
as relative.. But I failed to make it the correct way :(

And after it, just run "make" again and it build the whole project.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 meson.build   |  1 +
 qapi/meson.build  |  4 +++-
 trace/meson.build | 10 +++---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/meson.build b/meson.build
index f45ecf31bd..20d32fd20d 100644
--- a/meson.build
+++ b/meson.build
@@ -38,6 +38,7 @@ qemu_icondir = get_option('datadir') / 'icons'
 
 config_host_data = configuration_data()
 genh = []
+qapi_trace_events = []
 
 target_dirs = config_host['TARGET_DIRS'].split()
 have_linux_user = false
diff --git a/qapi/meson.build b/qapi/meson.build
index c0c49c15e4..333ca60583 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -114,7 +114,9 @@ foreach module : qapi_all_modules
   'qapi-events-@0@.h'.format(module),
   'qapi-commands-@0@.c'.format(module),
   'qapi-commands-@0@.h'.format(module),
+  'qapi-commands-@0@.trace-events'.format(module),
 ]
+qapi_trace_events += ['qapi-commands-@0@.trace-events'.format(module)]
   endif
   if module.endswith('-target')
 qapi_specific_outputs += qapi_module_outputs
@@ -126,7 +128,7 @@ endforeach
 qapi_files = custom_target('shared QAPI source files',
   output: qapi_util_outputs + qapi_specific_outputs + qapi_nonmodule_outputs,
   input: [ files('qapi-schema.json') ],
-  command: [ qapi_gen, '-o', 'qapi', '-b', '@INPUT0@' ],
+  command: [ qapi_gen, '-o', 'qapi', '-b', '@INPUT0@', '--add-trace-points' ],
   depend_files: [ qapi_inputs, qapi_gen_depends ])
 
 # Now go through all the outputs and add them to the right sourceset.
diff --git a/trace/meson.build b/trace/meson.build
index 573dd699c6..77e44fa68d 100644
--- a/trace/meson.build
+++ b/trace/meson.build
@@ -2,10 +2,14 @@
 specific_ss.add(files('control-target.c'))
 
 trace_events_files = []
-foreach dir : [ '.' ] + trace_events_subdirs
-  trace_events_file = meson.project_source_root() / dir / 'trace-events'
+foreach path : [ '.' ] + trace_events_subdirs + qapi_trace_events
+  if path.contains('trace-events')
+trace_events_file = meson.project_build_root() / 'qapi' / path
+  else
+trace_events_file = meson.project_source_root() / path / 'trace-events'
+  endif
   trace_events_files += [ trace_events_file ]
-  group_name = dir == '.' ? 'root' : dir.underscorify()
+  group_name = path == '.' ? 'root' : path.underscorify()
   group = '--group=' + group_name
   fmt = '@0@-' + group_name + '.@1@'
 
-- 
2.31.1




[PATCH 2/3] scripts/qapi-gen.py: add --add-trace-points option

2021-12-21 Thread Vladimir Sementsov-Ogievskiy
Add and option to generate trace points. We should generate both trace
points and trace-events files for further trace point code generation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 scripts/qapi/gen.py  | 13 ++---
 scripts/qapi/main.py | 10 +++---
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 995a97d2b8..605b3fe68a 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -251,7 +251,7 @@ def __init__(self,
 self._builtin_blurb = builtin_blurb
 self._pydoc = pydoc
 self._current_module: Optional[str] = None
-self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {}
+self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH, QAPIGen]] = {}
 self._main_module: Optional[str] = None
 
 @property
@@ -264,6 +264,11 @@ def _genh(self) -> QAPIGenH:
 assert self._current_module is not None
 return self._module[self._current_module][1]
 
+@property
+def _gent(self) -> QAPIGen:
+assert self._current_module is not None
+return self._module[self._current_module][2]
+
 @staticmethod
 def _module_dirname(name: str) -> str:
 if QAPISchemaModule.is_user_module(name):
@@ -293,7 +298,8 @@ def _add_module(self, name: str, blurb: str) -> None:
 basename = self._module_filename(self._what, name)
 genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
 genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
-self._module[name] = (genc, genh)
+gent = QAPIGen(basename + '.trace-events')
+self._module[name] = (genc, genh, gent)
 self._current_module = name
 
 @contextmanager
@@ -304,11 +310,12 @@ def _temp_module(self, name: str) -> Iterator[None]:
 self._current_module = old_module
 
 def write(self, output_dir: str, opt_builtins: bool = False) -> None:
-for name, (genc, genh) in self._module.items():
+for name, (genc, genh, gent) in self._module.items():
 if QAPISchemaModule.is_builtin_module(name) and not opt_builtins:
 continue
 genc.write(output_dir)
 genh.write(output_dir)
+gent.write(output_dir)
 
 def _begin_builtin_module(self) -> None:
 pass
diff --git a/scripts/qapi/main.py b/scripts/qapi/main.py
index f2ea6e0ce4..3adf0319cf 100644
--- a/scripts/qapi/main.py
+++ b/scripts/qapi/main.py
@@ -32,7 +32,8 @@ def generate(schema_file: str,
  output_dir: str,
  prefix: str,
  unmask: bool = False,
- builtins: bool = False) -> None:
+ builtins: bool = False,
+ add_trace_points: bool = False) -> None:
 """
 Generate C code for the given schema into the target directory.
 
@@ -49,7 +50,7 @@ def generate(schema_file: str,
 schema = QAPISchema(schema_file)
 gen_types(schema, output_dir, prefix, builtins)
 gen_visit(schema, output_dir, prefix, builtins)
-gen_commands(schema, output_dir, prefix)
+gen_commands(schema, output_dir, prefix, add_trace_points)
 gen_events(schema, output_dir, prefix)
 gen_introspect(schema, output_dir, prefix, unmask)
 
@@ -74,6 +75,8 @@ def main() -> int:
 parser.add_argument('-u', '--unmask-non-abi-names', action='store_true',
 dest='unmask',
 help="expose non-ABI names in introspection")
+parser.add_argument('--add-trace-points', action='store_true',
+help="add trace points to qmp marshals")
 parser.add_argument('schema', action='store')
 args = parser.parse_args()
 
@@ -88,7 +91,8 @@ def main() -> int:
  output_dir=args.output_dir,
  prefix=args.prefix,
  unmask=args.unmask,
- builtins=args.builtins)
+ builtins=args.builtins,
+ add_trace_points=args.add_trace_points)
 except QAPIError as err:
 print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
 return 1
-- 
2.31.1




Re: [PATCH] tests/qtest/virtio-net-failover: Use g_random_int() instead of g_test_rand_int()

2021-12-21 Thread Richard Henderson

On 12/21/21 2:32 AM, Thomas Huth wrote:
Using g_file_open_tmp is certainly better ... but the tests are currently written in a way 
where they require the file name of the temporary file - so switching to g_file_open_tmp() 
(which only provides a file handle) certainly would need some rewrite here...


Incorrect.  g_file_open_tmp returns the open file handle, but also returns the filename in 
*name_used.


I should think you can close the file handle straight away and use the filename.


r~



Re: [PULL v2 00/36] ui: D-Bus display backend

2021-12-21 Thread Richard Henderson

On 12/20/21 10:58 PM, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

The following changes since commit 2bf40d0841b942e7ba12953d515e62a436f0af84:

   Merge tag 'pull-user-20211220' of https://gitlab.com/rth7680/qemu into 
staging (2021-12-20 13:20:07 -0800)

are available in the Git repository at:

   https://gitlab.com/marcandre.lureau/qemu.git tags/dbus-pull-request

for you to fetch changes up to 89f4df9595e162ce4cc65f31a994a31e3e45ff3a:

   MAINTAINERS: update D-Bus section (2021-12-21 10:50:22 +0400)


Add D-Bus display backend



v2:
  - fix Cocoa build
  - fix 6.2->7.0 version annotations

Marc-André Lureau (36):
   ui/vdagent: add CHECK_SPICE_PROTOCOL_VERSION
   ui/vdagent: replace #if 0 with protocol version check
   ui: generalize clipboard notifier
   ui/vdagent: add serial capability support
   ui/clipboard: add qemu_clipboard_check_serial()
   ui/clipboard: add a clipboard reset serial event
   hw/display: report an error if virgl initialization failed
   virtio-gpu: use VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP
   ui: do not delay further remote resize
   ui: factor out qemu_console_set_display_gl_ctx()
   ui: associate GL context outside of display listener registration
   ui: make gl_block use a counter
   ui: add a gl-unblock warning timer
   ui: simplify gl unblock & flush
   ui: dispatch GL events to all listeners
   ui: split the GL context in a different object
   ui: move qemu_spice_fill_device_address to ui/util.c
   console: save current scanout details
   scripts: teach modinfo to skip non-C sources
   docs/sphinx: add sphinx modules to include D-Bus documentation
   backends: move dbus-vmstate1.xml to backends/
   docs: move D-Bus VMState documentation to source XML
   docs: add dbus-display documentation
   build-sys: set glib dependency version
   ui: add a D-Bus display backend
   ui/dbus: add p2p=on/off option
   tests/qtests: add qtest_qmp_add_client()
   tests: start dbus-display-test
   audio: add "dbus" audio backend
   ui/dbus: add clipboard interface
   chardev: teach socket to accept no addresses
   chardev: make socket derivable
   option: add g_auto for QemuOpts
   ui/dbus: add chardev backend & interface
   ui/dbus: register D-Bus VC handler
   MAINTAINERS: update D-Bus section

  docs/conf.py|   8 +
  docs/interop/dbus-display.rst   |  31 ++
  docs/interop/dbus-vmstate.rst   |  52 +--
  docs/interop/dbus.rst   |   2 +
  docs/interop/index.rst  |   1 +
  docs/sphinx/dbusdoc.py  | 166 +++
  docs/sphinx/dbusdomain.py   | 406 +
  docs/sphinx/dbusparser.py   | 373 
  docs/sphinx/fakedbusdoc.py  |  25 ++
  configure   |   1 +
  meson.build |  22 +-
  qapi/audio.json |   3 +-
  qapi/char.json  |  27 ++
  qapi/misc.json  |   4 +-
  qapi/ui.json|  34 +-
  audio/audio_int.h   |   7 +
  audio/audio_template.h  |   2 +
  include/chardev/char-socket.h   |  86 
  include/qemu/cutils.h   |   5 +
  include/qemu/dbus.h |  24 +
  include/qemu/option.h   |   2 +
  include/ui/clipboard.h  |  55 ++-
  include/ui/console.h|  70 ++-
  include/ui/dbus-display.h   |  17 +
  include/ui/dbus-module.h|  11 +
  include/ui/egl-context.h|   6 +-
  include/ui/gtk.h|  11 +-
  include/ui/sdl2.h   |   7 +-
  include/ui/spice-display.h  |   5 +-
  tests/qtest/libqos/libqtest.h   |  10 +
  ui/dbus.h   | 144 ++
  audio/audio.c   |   1 +
  audio/dbusaudio.c   | 654 +++
  chardev/char-socket.c   |  72 +--
  hw/display/qxl.c|   7 +-
  hw/display/vhost-user-gpu.c |   2 +-
  hw/display/virtio-gpu-base.c|   5 +-
  hw/display/virtio-gpu-virgl.c   |   3 +-
  hw/display/virtio-vga.c |  11 -
  monitor/qmp-cmds.c  |  13 +
  tests/qtest/dbus-display-test.c | 257 +++
  tests/qtest/libqtest.c  |  19 +
  ui/clipboard.c  |  34 +-
  ui/console.c| 305 +
  ui/dbus-chardev.c   | 296 +
  ui/dbus-clipboard.c | 457 +++
  ui/dbus-console.c   | 497 +
  ui/dbus-error.c |  48 ++
  ui/dbus-listener.c  | 486 
  ui/dbus-module.c|  35 ++
  ui/dbus.c   | 482 
  ui/egl-context.c|   6 +-
  ui/egl-headless.c   |  20 +-
  ui/gtk-clipboard.c  |  23 +-
  ui/gtk-egl.c|  12 +-
  ui/gtk-gl-area.c|  10 +-
  ui/gtk.c|  28 

Re: [PATCH] vfio/pci: Don't setup VFIO MSI-X for Kunlun VF

2021-12-21 Thread Alex Williamson
On Tue, 14 Dec 2021 13:45:34 +0800
Cai Huoqing  wrote:

> No support MSI-X in BAIDU KUNLUN Virtual Function devices,
> so add a quirk to avoid setuping VFIO MSI-X
> 
> Signed-off-by: Cai Huoqing 
> ---
>  hw/vfio/pci.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 7b45353ce2..15f76bbe56 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -1994,6 +1994,13 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, 
> uint8_t pos, Error **errp)
>  ret = vfio_setup_pcie_cap(vdev, pos, size, errp);
>  break;
>  case PCI_CAP_ID_MSIX:
> +/*
> + * BAIDU KUNLUN Virtual Function devices for KUNLUN AI processor
> + * don't support MSI-X, so don't setup VFIO MSI-X here.
> + */
> +if (vdev->vendor_id == PCI_VENDOR_ID_BAIDU &&
> +vdev->device_id == PCI_DEVICE_ID_KUNLUN_VF)
> +break;
>  ret = vfio_msix_setup(vdev, pos, errp);
>  break;
>  case PCI_CAP_ID_PM:


So the VF exposes an MSI-X capability but it's entirely unsupported
and/or bogus?  If it's not bogus, why can't we support it?  How does
the host kernel driver know to avoid MSI-X?  Should we use the same
mechanism used by the host driver to quirk whether vfio-pci exposes the
MSI-X capability to userspace at all?  Thanks,

Alex




RE: [PATCH v7 05/13] target/hexagon: introduce new helper functions

2021-12-21 Thread Taylor Simpson


> -Original Message-
> From: Anton Johansson 
> Sent: Friday, December 17, 2021 2:01 AM
> To: qemu-devel@nongnu.org
> Cc: a...@rev.ng; Taylor Simpson ; Brian Cain
> ; bab...@rev.ng; ni...@rev.ng;
> richard.hender...@linaro.org
> Subject: [PATCH v7 05/13] target/hexagon: introduce new helper functions
> 
> From: Niccolò Izzo 
> 
> These helpers will be employed by the idef-parser generated code.
> "Helper" can here mean two things, a helper in the QEMU sense added to
> `helper.h` and `op_helper.c`, but also helper functions providing a manual
> TCG implementation of a certain features.
> 
> Signed-off-by: Alessandro Di Federico 
> Signed-off-by: Niccolò Izzo 
> Signed-off-by: Anton Johansson 
> ---
>  target/hexagon/genptr.c| 166
> +++--
>  target/hexagon/genptr.h|  16 +++-
>  target/hexagon/helper.h|   2 +
>  target/hexagon/macros.h|   9 ++
>  target/hexagon/op_helper.c |  10 +++
>  5 files changed, 195 insertions(+), 8 deletions(-)
> 
> diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
> ae798e921e..44a1ec9ccf 100644
> +void gen_satu_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int
> +width) {
> +gen_sat_i64(dest, source, width);

Should be gen_satu_i64 (unsigned)


> +TCGv_i64 ovfl_64 = tcg_temp_new_i64();
> +tcg_gen_setcond_i64(TCG_COND_NE, ovfl_64, dest, source);
> +tcg_gen_trunc_i64_tl(ovfl, ovfl_64);
> +tcg_temp_free_i64(ovfl_64);
> +}



RE: [PATCH v7 09/13] target/hexagon: import lexer for idef-parser

2021-12-21 Thread Taylor Simpson


> -Original Message-
> From: Anton Johansson 
> Sent: Friday, December 17, 2021 2:01 AM
> To: qemu-devel@nongnu.org
> Cc: a...@rev.ng; Taylor Simpson ; Brian Cain
> ; bab...@rev.ng; ni...@rev.ng;
> richard.hender...@linaro.org
> Subject: [PATCH v7 09/13] target/hexagon: import lexer for idef-parser
> 
> From: Paolo Montesel 
> 
> Signed-off-by: Alessandro Di Federico 
> Signed-off-by: Paolo Montesel 
> Signed-off-by: Anton Johansson 
> ---
>  target/hexagon/idef-parser/idef-parser.h   | 259 ++
>  target/hexagon/idef-parser/idef-parser.lex | 571
> +
>  target/hexagon/meson.build |   4 +
>  3 files changed, 834 insertions(+)
>  create mode 100644 target/hexagon/idef-parser/idef-parser.h
>  create mode 100644 target/hexagon/idef-parser/idef-parser.lex
> 
> diff --git a/target/hexagon/idef-parser/idef-parser.lex
> b/target/hexagon/idef-parser/idef-parser.lex
> new file mode 100644
> index 00..c7466c47f4
> --- /dev/null
> +++ b/target/hexagon/idef-parser/idef-parser.lex
> +"fSATN"  { yylval->sat.set_overflow = true;
> +   yylval->sat.signedness = SIGNED;
> +   return SAT; }
> +"fVSATN" { yylval->sat.set_overflow = false;
> +   yylval->sat.signedness = SIGNED;
> +   return SAT; }
> +"fSATUN" { yylval->sat.set_overflow = false;

This should be true, just like fSATN.  Take a look at the satuh and satub 
instructions.

I tried changing it to true to make satuh and satub work.  However, the 
vaddubs, vadduhs, vsatub, vsatwuh, vsububs, and other instructions don't work.  
I've attached a test case that demonstrates this problem.

When the value is set to false, the test case prints
ERROR at line 71: 0x != 0x0001
ERROR at line 75: 0x != 0x0001
ERROR at line 106: 0x != 0x0001
FAIL

When the value is set to true, the test case prints
ERROR at line 105: 0x007f != 0x00ff
ERROR at line 106: 0x != 0x0001
FAIL

Without your changes, the test case prints
PASS



> +   yylval->sat.signedness = UNSIGNED;
> +   return SAT; }
/*
 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  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 
#include 

int err;

static void __check32(int line, int val, int expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%08x != 0x%08x\n", line, val, expect);
err++;
}
}

#define check32(RES, EXP) __check32(__LINE__, RES, EXP)

static void __check64(int line, long long val, long long expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%016llx != 0x%016llx\n", line, val, expect);
err++;
}
}

#define check64(RES, EXP) __check64(__LINE__, RES, EXP)

static uint32_t satub(uint32_t src, int *ovf_result)
{
uint32_t result;
uint32_t usr;

/*
 * This instruction can set bit 0 (OVF/overflow) in usr
 * Clear the bit first, then return that bit to the caller
 */
asm volatile("r2 = usr\n\t"
 "r2 = clrbit(r2, #0)\n\t"/* clear overflow bit */
 "usr = r2\n\t"
 "%0 = satub(%2)\n\t"
 "%1 = usr\n\t"
 : "=r"(result), "=r"(usr)
 : "r"(src)
 : "r2", "usr");
*ovf_result = (usr & 1);
return result;
}

static void test_satub(void)
{
uint32_t result;
int ovf_result;

result = satub(0xfff, _result);
check32(result, 0xff);
check32(ovf_result, 1);

result = satub(-1, _result);
check32(result, 0);
check32(ovf_result, 1);
}

static uint64_t vaddubs(uint64_t src1, uint64_t src2, int *ovf_result)
{
uint64_t result;
uint32_t usr;

/*
 * This instruction can set bit 0 (OVF/overflow) in usr
 * Clear the bit first, then return that bit to the caller
 */
asm volatile("r2 = usr\n\t"
 "r2 = clrbit(r2, #0)\n\t"/* clear overflow bit */
 "usr = r2\n\t"
 "%0 = vaddub(%2, %3):sat\n\t"
 "%1 = usr\n\t"
 : "=r"(result), "=r"(usr)
 : "r"(src1), "r"(src2)
 : "r2", "usr");
*ovf_result = (usr & 1);

Re: [PATCH] vl: Add -set options to device opts dict when using JSON syntax for -device

2021-12-21 Thread Damien Hedde




On 12/21/21 16:40, Markus Armbruster wrote:

Paolo Bonzini  writes:


On 12/21/21 13:58, Markus Armbruster wrote:

Is this a regression?  I suspect commit 5dacda5167 "vl: Enable JSON
syntax for -device" (v6.2.0).


Obviously not a regression: everything that used to work still works.


FWIW I think -set should be deprecated.  I'm not aware of any
particularly useful use of it.  There are a couple in the QEMU tests
(in vhost-user-test and in qemu-iotests 068), but in both cases the
code would be easier to follow without; patches can be dusted off if
desired.


-set has its uses, but they're kind of obscure.  When you want to use
some canned configuration with slight modifications, then -readconfig
canned.cfg -set ... is nicer than editing a copy of canned.cfg.  For
what it's worth, we have a few cans in docs/config/, and we refer to at
least one of them in the manual (in docs/system/devices/usb.rst).

There are a few really good ideas in QemuOpts.  I count -readconfig,
-writeconfig and -set among them.  Unfortunately, they have been marred
by us not converting the whole CLI to QemuOpts as envisaged.  And now we
never will, because our needs have long outgrown what QemuOpts can
provide.

I'd love to have unmarred, QAPI-based replacements.  However, I doubt
maintaining backwards compatibility will be practical and worthwhile.

Declare these options unstable?



I agree.

Without QemuOpts, and more precisely the ability to alter them before 
they are really handled, this kind of feature will be impossible to have.


Only way I see, is to reverse the mechanism:
+ handle set option before, it store the key,value somewhere
+ an option like -device checks that store and fetch their values.

--
Damien



Re: [PATCH] vl: Add -set options to device opts dict when using JSON syntax for -device

2021-12-21 Thread Damien Hedde




On 12/21/21 16:40, Markus Armbruster wrote:

Paolo Bonzini  writes:


On 12/21/21 13:58, Markus Armbruster wrote:

Is this a regression?  I suspect commit 5dacda5167 "vl: Enable JSON
syntax for -device" (v6.2.0).


Obviously not a regression: everything that used to work still works.


FWIW I think -set should be deprecated.  I'm not aware of any
particularly useful use of it.  There are a couple in the QEMU tests
(in vhost-user-test and in qemu-iotests 068), but in both cases the
code would be easier to follow without; patches can be dusted off if
desired.


-set has its uses, but they're kind of obscure.  When you want to use
some canned configuration with slight modifications, then -readconfig
canned.cfg -set ... is nicer than editing a copy of canned.cfg.  For
what it's worth, we have a few cans in docs/config/, and we refer to at
least one of them in the manual (in docs/system/devices/usb.rst).

There are a few really good ideas in QemuOpts.  I count -readconfig,
-writeconfig and -set among them.  Unfortunately, they have been marred
by us not converting the whole CLI to QemuOpts as envisaged.  And now we
never will, because our needs have long outgrown what QemuOpts can
provide.

I'd love to have unmarred, QAPI-based replacements.  However, I doubt
maintaining backwards compatibility will be practical and worthwhile.

Declare these options unstable?



I agree.

Without QemuOpts, and more precisely the ability to alter them before 
they are really handled, this kind of feature will be impossible to have.


Only way I see, is to reverse the mechanism:
+ handle set option before, it store the key,value somewhere
+ an option like -device checks that store and fetch their values.

--
Damien




[PATCH] target/riscv: make H-extension non-experimental

2021-12-21 Thread Vineet Gupta
H-ext v1.0 was ratified recently as part of Privileged Spec 1.12.
So move it out of experimental.

[1] https://wiki.riscv.org/display/TECH/Recently+Ratified+Extensions

Signed-off-by: Vineet Gupta 
---
 target/riscv/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6ef3314bced8..a582179b1773 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -640,12 +640,12 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
 DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 
-/* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
 DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
 DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
 DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
-DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
+DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, false),
+/* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-- 
2.30.2




Re: [PATCH v11 00/31] LoongArch64 port of QEMU TCG

2021-12-21 Thread Richard Henderson

On 12/20/21 9:40 PM, WANG Xuerui wrote:

Hi all,

This is a port of QEMU TCG to the brand-new CPU architecture LoongArch,
introduced by Loongson with their 3A5000 chips.

Everything is tested on real 3A5000 board (system emulation, linux-user,
make check) and GitLab (CI jobs), and rebased to latest master branch.

## About the series

Only the LP64D ABI is supported, as this is the only one fully
implemented and supported by Loongson so far. 32-bit support is incomplete
from outset, and removed from the very latest upstream submissions, so you
can't even configure for that.

The architecture's documentation is already translated into English;
it can be browsed at https://loongson.github.io/LoongArch-Documentation/.
The LoongArch ELF psABI doc (version 1.00) could be found at [1];
if anything is missing there, it's most likely the same as RISC-V, but
you can always raise an issue over their issue tracker at [2].

[1]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
[2]: https://github.com/loongson/LoongArch-Documentation/issues

In this series I made use of generated instruction encodings and
emitters from https://github.com/loongson-community/loongarch-opcodes
(a community project started by myself, something I must admit), as the
LoongArch encoding is highly irregular even for a fixed 32-bit ISA, and
I want to minimize the maintenance burden for future collaboration.

This series touches some of the same files as Song Gao's previous
submission of LoongArch *target* support, which is a bit unfortunate;
one of us will have to rebase after either series gets in. Actual
conflict should only happen on build system bits and include/elf.h,
though, as we're working on entirely different areas.

## How to build and test this

Upstream support for LoongArch is largely WIP for now, which means you
must apply a lot of patches if you want to even cross-build for this arch.
The main sources I used are as follows:

* binutils: (already upstream as of November 2021)
* gcc: https://github.com/xen0n/gcc/tree/for-gentoo-gcc-12-v5
   based on https://github.com/loongson/gcc/tree/loongarch_upstream_v3
* glibc: https://github.com/xen0n/glibc/tree/for-gentoo-glibc-2.34-v3
   based on https://github.com/loongson/glibc/tree/loongarch_2_34_dev
* Linux: https://github.com/xen0n/linux/tree/loongarch-playground-v7
   based on https://github.com/loongson/linux/tree/loongarch-next
* Gentoo overlay: https://github.com/xen0n/loongson-overlay

I have made ready-to-use Gentoo stage3 tarballs, but they're served with
CDN off my personal cloud account, and I don't want the link to be
exposed so that my bills skyrocket; you can reach me off-list to get the
links if you're interested.

As for the hardware availability, the boards can already be bought in
China on Taobao, and I think some people at Loongson might be able to
arrange for testing environments, if testing on real hardware other than
mine is required before merging; they have their in-house Debian spin-off
from the early days of this architecture. Their kernel is
ABI-incompatible with the version being upstreamed and used by me, but
QEMU should work there regardless.

Lastly, I'm new to QEMU development and this is my first patch series
here; apologizes if I get anything wrong, and any help or suggestion is
certainly appreciated!

## Changelog

v11 -> v10:

- Rebased to latest development branch


Awesome, thanks.  I was just about to ask if you could update for Paolo's meson.build 
changes.  I've tagged the PR for the initial commit, and it'll go in next.



r~



[PULL 31/31] tests/docker: Add gentoo-loongarch64-cross image and run cross builds in GitLab

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Normally this would be based on qemu/debian10 or qemu/ubuntu2004, but
after a week-long struggle, I still cannot build stage2 gcc with the
known-good LoongArch toolchain sources, so I chose the least-resistance
path with Gentoo as base image. As this image is not expected to be
re-built by CI, like hexagon, it should not take much maintenance
effort; also it's expected to be replaced as soon as Debian is
available.

As the LoongArch *target* has not been merged yet, a check-tcg job is
not added at the moment, but cross builds with the TCG *host* port are
already possible, and added to CI matrix.

Due to constant flux of the toolchain sources used (especially that of
glibc), the binaries built with this image may or may not work when
run on actual hardware, but still useful for ensuring things correctly
build. This image is expected to be updated every once in a while,
before everything settles down.

As a reference, the image takes about 25 minutes to rebuild on a
Threadripper 3990X system with Docker operating on HDD; YMMV but it
probably wouldn't become significantly shorter, as everything needs to
be built from source in our case.

Signed-off-by: WANG Xuerui 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-32-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 .gitlab-ci.d/container-cross.yml  |  27 
 .gitlab-ci.d/crossbuilds.yml  |  19 +++
 MAINTAINERS   |   2 +
 tests/docker/Makefile.include |  21 +++
 .../gentoo-loongarch64-cross.docker   |  21 +++
 .../build-toolchain.sh| 128 ++
 6 files changed, 218 insertions(+)
 create mode 100644 tests/docker/dockerfiles/gentoo-loongarch64-cross.docker
 create mode 100755 
tests/docker/dockerfiles/gentoo-loongarch64-cross.docker.d/build-toolchain.sh

diff --git a/.gitlab-ci.d/container-cross.yml b/.gitlab-ci.d/container-cross.yml
index a3b5b90552..7a8cc556cc 100644
--- a/.gitlab-ci.d/container-cross.yml
+++ b/.gitlab-ci.d/container-cross.yml
@@ -82,6 +82,33 @@ hppa-debian-cross-container:
   variables:
 NAME: debian-hppa-cross
 
+# Similar to hexagon, we don't want to build loongarch64 in the CI either.
+loongarch64-cross-container:
+  image: docker:stable
+  stage: containers
+  rules:
+- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
+  when: never
+- when: always
+  variables:
+NAME: gentoo-loongarch64-cross
+GIT_DEPTH: 1
+  services:
+- docker:dind
+  before_script:
+- export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
+- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
+- docker info
+- docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
+  script:
+- echo "TAG:$TAG"
+- echo "COMMON_TAG:$COMMON_TAG"
+- docker pull $COMMON_TAG
+- docker tag $COMMON_TAG $TAG
+- docker push "$TAG"
+  after_script:
+- docker logout
+
 m68k-debian-cross-container:
   extends: .container_job_template
   stage: containers-layer2
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
index 17d6cb3e45..b1cbc9cc43 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -68,6 +68,25 @@ cross-i386-tci:
 EXTRA_CONFIGURE_OPTS: 
--target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user
 MAKE_CHECK_ARGS: check check-tcg
 
+# Upstream LoongArch support is still incomplete, but toolchain is already
+# usable and partially merged, so the host support is already testable; but
+# don't let failures block CI.
+cross-loongarch64-system:
+  extends: .cross_system_build_job
+  allow_failure: true
+  needs:
+job: loongarch64-cross-container
+  variables:
+IMAGE: gentoo-loongarch64-cross
+
+cross-loongarch64-user:
+  extends: .cross_user_build_job
+  allow_failure: true
+  needs:
+job: loongarch64-cross-container
+  variables:
+IMAGE: gentoo-loongarch64-cross
+
 cross-mips-system:
   extends: .cross_system_build_job
   needs:
diff --git a/MAINTAINERS b/MAINTAINERS
index 4f6e0de3fb..8da7071b01 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3143,6 +3143,8 @@ LoongArch64 TCG target
 M: WANG Xuerui 
 S: Maintained
 F: tcg/loongarch64/
+F: tests/docker/dockerfiles/gentoo-loongarch64-cross.docker
+F: tests/docker/dockerfiles/gentoo-loongarch64-cross.docker.d/
 
 MIPS TCG target
 M: Philippe Mathieu-Daudé 
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index f1a0c5db7a..a2cdf193bb 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -176,6 +176,27 @@ docker-image-debian-hexagon-cross: 
$(DOCKER_FILES_DIR)/debian-hexagon-cross.dock
qemu/debian-hexagon-cross --add-current-user,   
\
"PREPARE", "debian-hexagon-cross"))
 
+#
+# Same for loongarch64-cross.
+#
+docker-image-gentoo-loongarch64-cross: 

[PULL 29/31] linux-user: Implement CPU-specific signal handler for loongarch64 hosts

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-30-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 linux-user/host/loongarch64/host-signal.h | 87 +++
 1 file changed, 87 insertions(+)
 create mode 100644 linux-user/host/loongarch64/host-signal.h

diff --git a/linux-user/host/loongarch64/host-signal.h 
b/linux-user/host/loongarch64/host-signal.h
new file mode 100644
index 00..05e2c82371
--- /dev/null
+++ b/linux-user/host/loongarch64/host-signal.h
@@ -0,0 +1,87 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LOONGARCH64_HOST_SIGNAL_H
+#define LOONGARCH64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.__pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+uc->uc_mcontext.__pc = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+const uint32_t *pinsn = (const uint32_t *)host_signal_pc(uc);
+uint32_t insn = pinsn[0];
+
+/* Detect store by reading the instruction at the program counter.  */
+switch ((insn >> 26) & 0b11) {
+case 0b001000: /* {ll,sc}.[wd] */
+switch ((insn >> 24) & 0b11) {
+case 0b01: /* sc.w */
+case 0b11: /* sc.d */
+return true;
+}
+break;
+case 0b001001: /* {ld,st}ox4.[wd] ({ld,st}ptr.[wd]) */
+switch ((insn >> 24) & 0b11) {
+case 0b01: /* stox4.w (stptr.w) */
+case 0b11: /* stox4.d (stptr.d) */
+return true;
+}
+break;
+case 0b001010: /* {ld,st}.* family */
+switch ((insn >> 22) & 0b) {
+case 0b0100: /* st.b */
+case 0b0101: /* st.h */
+case 0b0110: /* st.w */
+case 0b0111: /* st.d */
+case 0b1101: /* fst.s */
+case 0b: /* fst.d */
+return true;
+}
+break;
+case 0b001110: /* indexed, atomic, bounds-checking memory operations */
+uint32_t sel = (insn >> 15) & 0b111;
+
+switch (sel) {
+case 0b010: /* stx.b */
+case 0b0101000: /* stx.h */
+case 0b011: /* stx.w */
+case 0b0111000: /* stx.d */
+case 0b111: /* fstx.s */
+case 0b000: /* fstx.d */
+case 0b00011101100: /* fstgt.s */
+case 0b00011101101: /* fstgt.d */
+case 0b00011101110: /* fstle.s */
+case 0b0001110: /* fstle.d */
+case 0b0001000: /* stgt.b */
+case 0b0001001: /* stgt.h */
+case 0b0001010: /* stgt.w */
+case 0b0001011: /* stgt.d */
+case 0b0001100: /* stle.b */
+case 0b0001101: /* stle.h */
+case 0b0001110: /* stle.w */
+case 0b000: /* stle.d */
+case 0b0001100 ... 0b00011100011: /* am* insns */
+return true;
+}
+break;
+}
+
+return false;
+}
+
+#endif
-- 
2.25.1




[PULL 28/31] common-user: Add safe syscall handling for loongarch64 hosts

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-29-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 .../host/loongarch64/safe-syscall.inc.S   | 90 +++
 1 file changed, 90 insertions(+)
 create mode 100644 common-user/host/loongarch64/safe-syscall.inc.S

diff --git a/common-user/host/loongarch64/safe-syscall.inc.S 
b/common-user/host/loongarch64/safe-syscall.inc.S
new file mode 100644
index 00..b88a069c45
--- /dev/null
+++ b/common-user/host/loongarch64/safe-syscall.inc.S
@@ -0,0 +1,90 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Ported to LoongArch by WANG Xuerui 
+ *
+ * Based on safe-syscall.inc.S code for RISC-V,
+ * originally written by Richard Henderson 
+ * Copyright (C) 2018 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+.global safe_syscall_base
+.global safe_syscall_start
+.global safe_syscall_end
+.type   safe_syscall_base, @function
+.type   safe_syscall_start, @function
+.type   safe_syscall_end, @function
+
+/*
+ * This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+.cfi_startproc
+/*
+ * The syscall calling convention is nearly the same as C:
+ * we enter with a0 == _pending
+ *   a1 == syscall number
+ *   a2 ... a7 == syscall arguments
+ *   and return the result in a0
+ * and the syscall instruction needs
+ *   a7 == syscall number
+ *   a0 ... a5 == syscall arguments
+ *   and returns the result in a0
+ * Shuffle everything around appropriately.
+ */
+move$t0, $a0/* signal_pending pointer */
+move$t1, $a1/* syscall number */
+move$a0, $a2/* syscall arguments */
+move$a1, $a3
+move$a2, $a4
+move$a3, $a5
+move$a4, $a6
+move$a5, $a7
+move$a7, $t1
+
+/*
+ * We need to preserve the signal_pending pointer but t0 is
+ * clobbered by syscalls on LoongArch, so we need to move it
+ * somewhere else, ideally both preserved across syscalls and
+ * clobbered by procedure calls so we don't have to allocate a
+ * stack frame; a6 is just the register we want here.
+ */
+move$a6, $t0
+
+/*
+ * This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+/* If signal_pending is non-zero, don't do the call */
+ld.w$t1, $a6, 0
+bnez$t1, 2f
+syscall 0
+safe_syscall_end:
+/* code path for having successfully executed the syscall */
+li.w$t2, -4096
+bgtu$a0, $t2, 0f
+jr  $ra
+
+/* code path setting errno */
+0:  sub.d   $a0, $zero, $a0
+b   safe_syscall_set_errno_tail
+
+/* code path when we didn't execute the syscall */
+2:  li.w$a0, QEMU_ERESTARTSYS
+b   safe_syscall_set_errno_tail
+.cfi_endproc
+.size   safe_syscall_base, .-safe_syscall_base
-- 
2.25.1




[PULL 24/31] tcg/loongarch64: Implement tcg_target_qemu_prologue

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-25-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 68 
 1 file changed, 68 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index f67d5fa110..0b7d6458c5 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -968,6 +968,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
  * Entry-points
  */
 
+static const tcg_insn_unit *tb_ret_addr;
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1517,3 +1519,69 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 g_assert_not_reached();
 }
 }
+
+static const int tcg_target_callee_save_regs[] = {
+TCG_REG_S0, /* used for the global env (TCG_AREG0) */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_RA, /* should be last for ABI compliance */
+};
+
+/* Stack frame parameters.  */
+#define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
+#define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
+#define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
+#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
+ + TCG_TARGET_STACK_ALIGN - 1) \
+& -TCG_TARGET_STACK_ALIGN)
+#define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
+
+/* We're expecting to be able to use an immediate for frame allocation.  */
+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff);
+
+/* Generate global QEMU prologue and epilogue code */
+static void tcg_target_qemu_prologue(TCGContext *s)
+{
+int i;
+
+tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
+
+/* TB prologue */
+tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+#if !defined(CONFIG_SOFTMMU)
+if (USE_GUEST_BASE) {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
+tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+}
+#endif
+
+/* Call generated code */
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
+
+/* Return path for goto_ptr. Set return value to 0 */
+tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
+tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
+
+/* TB epilogue */
+tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
+tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0);
+}
-- 
2.25.1




[PULL 30/31] configure, meson.build: Mark support for loongarch64 hosts

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Example output of `uname -a` on an initial Gentoo LA64 port, running
the upstream submission version of Linux (with some very minor patches
not influencing output here):

> Linux  5.14.0-10342-g37a00851b145 #5 SMP PREEMPT Tue Aug 10 
> 12:56:24 PM CST 2021 loongarch64 GNU/Linux

And the same on the vendor-supplied Loongnix 20 system, with an early
in-house port of Linux, and using the old-world ABI:

> Linux  4.19.167-rc5.lnd.1-loongson-3 #1 SMP Sat Apr 17 07:32:32 UTC 
> 2021 loongarch64 loongarch64 loongarch64 GNU/Linux

So a name of "loongarch64" matches both, fortunately.

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-31-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 configure   | 5 +
 meson.build | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 8ccfe51673..9724631609 100755
--- a/configure
+++ b/configure
@@ -631,6 +631,8 @@ elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
   cpu="aarch64"
+elif check_define __loongarch64 ; then
+  cpu="loongarch64"
 else
   cpu=$(uname -m)
 fi
@@ -3719,6 +3721,9 @@ if test "$linux" = "yes" ; then
   aarch64)
 linux_arch=arm64
 ;;
+  loongarch*)
+linux_arch=loongarch
+;;
   mips64)
 linux_arch=mips
 ;;
diff --git a/meson.build b/meson.build
index f45ecf31bd..6d7c02bad7 100644
--- a/meson.build
+++ b/meson.build
@@ -56,7 +56,7 @@ python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
-  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
 
 cpu = host_machine.cpu_family()
 
-- 
2.25.1




[PULL 23/31] tcg/loongarch64: Add softmmu load/store helpers, implement qemu_ld/qemu_st ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-24-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |   2 +
 tcg/loongarch64/tcg-target.c.inc | 353 +++
 2 files changed, 355 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index e54ca9b2de..349c672687 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -17,7 +17,9 @@
 C_O0_I1(r)
 C_O0_I2(rZ, r)
 C_O0_I2(rZ, rZ)
+C_O0_I2(LZ, L)
 C_O1_I1(r, r)
+C_O1_I1(r, L)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rI)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3d1d7c33c0..f67d5fa110 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -117,6 +117,11 @@ static const int tcg_target_call_oarg_regs[] = {
 TCG_REG_A1,
 };
 
+#ifndef CONFIG_SOFTMMU
+#define USE_GUEST_BASE (guest_base != 0)
+#define TCG_GUEST_BASE_REG TCG_REG_S1
+#endif
+
 #define TCG_CT_CONST_ZERO  0x100
 #define TCG_CT_CONST_S12   0x200
 #define TCG_CT_CONST_N12   0x400
@@ -632,6 +637,333 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 return false;
 }
 
+/*
+ * Load/store helpers for SoftMMU, and qemu_ld/st implementations
+ */
+
+#if defined(CONFIG_SOFTMMU)
+#include "../tcg-ldst.c.inc"
+
+/*
+ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ * MemOpIdx oi, uintptr_t ra)
+ */
+static void * const qemu_ld_helpers[4] = {
+[MO_8]  = helper_ret_ldub_mmu,
+[MO_16] = helper_le_lduw_mmu,
+[MO_32] = helper_le_ldul_mmu,
+[MO_64] = helper_le_ldq_mmu,
+};
+
+/*
+ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ * uintxx_t val, MemOpIdx oi,
+ * uintptr_t ra)
+ */
+static void * const qemu_st_helpers[4] = {
+[MO_8]  = helper_ret_stb_mmu,
+[MO_16] = helper_le_stw_mmu,
+[MO_32] = helper_le_stl_mmu,
+[MO_64] = helper_le_stq_mmu,
+};
+
+/* We expect to use a 12-bit negative offset from ENV.  */
+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
+
+static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
+{
+tcg_out_opc_b(s, 0);
+return reloc_br_sd10k16(s->code_ptr - 1, target);
+}
+
+/*
+ * Emits common code for TLB addend lookup, that eventually loads the
+ * addend in TCG_REG_TMP2.
+ */
+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi,
+ tcg_insn_unit **label_ptr, bool is_load)
+{
+MemOp opc = get_memop(oi);
+unsigned s_bits = opc & MO_SIZE;
+unsigned a_bits = get_alignment_bits(opc);
+tcg_target_long compare_mask;
+int mem_index = get_mmuidx(oi);
+int fast_ofs = TLB_MASK_TABLE_OFS(mem_index);
+int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask);
+int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table);
+
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
+
+tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl,
+TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0);
+tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1);
+
+/* Load the tlb comparator and the addend.  */
+tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2,
+   is_load ? offsetof(CPUTLBEntry, addr_read)
+   : offsetof(CPUTLBEntry, addr_write));
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2,
+   offsetof(CPUTLBEntry, addend));
+
+/* We don't support unaligned accesses.  */
+if (a_bits < s_bits) {
+a_bits = s_bits;
+}
+/* Clear the non-page, non-alignment bits from the address.  */
+compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask);
+tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl);
+
+/* Compare masked address with the TLB entry.  */
+label_ptr[0] = s->code_ptr;
+tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0);
+
+/* TLB Hit - addend in TCG_REG_TMP2, ready for use.  */
+}
+
+static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
+TCGType type,
+TCGReg datalo, TCGReg addrlo,
+void *raddr, tcg_insn_unit **label_ptr)
+{
+TCGLabelQemuLdst *label = new_ldst_label(s);
+
+label->is_ld = is_ld;
+label->oi = oi;
+label->type = type;
+label->datalo_reg = datalo;
+label->datahi_reg = 0; /* unused */
+label->addrlo_reg = addrlo;
+label->addrhi_reg = 0; /* unused */
+

[PULL 25/31] tcg/loongarch64: Implement exit_tb/goto_tb

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-26-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 0b7d6458c5..92a30b791a 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -980,6 +980,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 int c2 = const_args[2];
 
 switch (opc) {
+case INDEX_op_exit_tb:
+/* Reuse the zeroing that exists for goto_ptr.  */
+if (a0 == 0) {
+tcg_out_call_int(s, tcg_code_gen_epilogue, true);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
+tcg_out_call_int(s, tb_ret_addr, true);
+}
+break;
+
+case INDEX_op_goto_tb:
+assert(s->tb_jmp_insn_offset == 0);
+/* indirect jump method */
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
+   (uintptr_t)(s->tb_jmp_target_addr + a0));
+tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+set_jmp_reset_offset(s, a0);
+break;
+
 case INDEX_op_mb:
 tcg_out_mb(s, a0);
 break;
-- 
2.25.1




[PULL 08/31] tcg/loongarch64: Implement the memory barrier op

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-9-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 32 
 1 file changed, 32 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index a88ba9a253..615bed9096 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -234,3 +234,35 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 g_assert_not_reached();
 }
 }
+
+#include "tcg-insn-defs.c.inc"
+
+/*
+ * TCG intrinsics
+ */
+
+static void tcg_out_mb(TCGContext *s, TCGArg a0)
+{
+/* Baseline LoongArch only has the full barrier, unfortunately.  */
+tcg_out_opc_dbar(s, 0);
+}
+
+/*
+ * Entry-points
+ */
+
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+   const TCGArg args[TCG_MAX_OP_ARGS],
+   const int const_args[TCG_MAX_OP_ARGS])
+{
+TCGArg a0 = args[0];
+
+switch (opc) {
+case INDEX_op_mb:
+tcg_out_mb(s, a0);
+break;
+
+default:
+g_assert_not_reached();
+}
+}
-- 
2.25.1




[PULL 27/31] tcg/loongarch64: Register the JIT

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-28-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 44 
 1 file changed, 44 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 19bfc135f6..9cd46c9be3 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1631,3 +1631,47 @@ static void tcg_target_init(TCGContext *s)
 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
 }
+
+typedef struct {
+DebugFrameHeader h;
+uint8_t fde_def_cfa[4];
+uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_LOONGARCH
+
+static const DebugFrame debug_frame = {
+.h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
+.h.cie.id = -1,
+.h.cie.version = 1,
+.h.cie.code_align = 1,
+.h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
+.h.cie.return_column = TCG_REG_RA,
+
+/* Total FDE size does not include the "len" member.  */
+.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
+
+.fde_def_cfa = {
+12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ...  */
+(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
+(FRAME_SIZE >> 7)
+},
+.fde_reg_ofs = {
+0x80 + 23, 11,  /* DW_CFA_offset, s0, -88 */
+0x80 + 24, 10,  /* DW_CFA_offset, s1, -80 */
+0x80 + 25, 9,   /* DW_CFA_offset, s2, -72 */
+0x80 + 26, 8,   /* DW_CFA_offset, s3, -64 */
+0x80 + 27, 7,   /* DW_CFA_offset, s4, -56 */
+0x80 + 28, 6,   /* DW_CFA_offset, s5, -48 */
+0x80 + 29, 5,   /* DW_CFA_offset, s6, -40 */
+0x80 + 30, 4,   /* DW_CFA_offset, s7, -32 */
+0x80 + 31, 3,   /* DW_CFA_offset, s8, -24 */
+0x80 + 22, 2,   /* DW_CFA_offset, s9, -16 */
+0x80 + 1 , 1,   /* DW_CFA_offset, ra, -8 */
+}
+};
+
+void tcg_register_jit(const void *buf, size_t buf_size)
+{
+tcg_register_jit_int(buf, buf_size, _frame, sizeof(debug_frame));
+}
-- 
2.25.1




[PULL 21/31] tcg/loongarch64: Implement tcg_out_call

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-22-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 34 
 1 file changed, 34 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 23c151f473..151d3308ea 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -532,6 +532,39 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, 
TCGReg arg1,
 tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
 }
 
+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool 
tail)
+{
+TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
+ptrdiff_t offset = tcg_pcrel_diff(s, arg);
+
+tcg_debug_assert((offset & 3) == 0);
+if (offset == sextreg(offset, 0, 28)) {
+/* short jump: +/- 256MiB */
+if (tail) {
+tcg_out_opc_b(s, offset >> 2);
+} else {
+tcg_out_opc_bl(s, offset >> 2);
+}
+} else if (offset == sextreg(offset, 0, 38)) {
+/* long jump: +/- 256GiB */
+tcg_target_long lo = sextreg(offset, 0, 18);
+tcg_target_long hi = offset - lo;
+tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18);
+tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
+} else {
+/* far jump: 64-bit */
+tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18);
+tcg_target_long hi = (tcg_target_long)arg - lo;
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi);
+tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
+}
+}
+
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
+{
+tcg_out_call_int(s, arg, false);
+}
+
 /*
  * Entry-points
  */
@@ -882,6 +915,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
+case INDEX_op_call: /* Always emitted via tcg_out_call.  */
 default:
 g_assert_not_reached();
 }
-- 
2.25.1




[PULL 11/31] tcg/loongarch64: Implement sign-/zero-extension ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-12-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.h | 24 
 tcg/loongarch64/tcg-target.c.inc | 82 
 3 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 5cc4407367..7e459490ea 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,3 +15,4 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O1_I1(r, r)
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 25328646f0..a6d9e036fc 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -107,10 +107,10 @@ typedef enum {
 #define TCG_TARGET_HAS_muls2_i320
 #define TCG_TARGET_HAS_muluh_i320
 #define TCG_TARGET_HAS_mulsh_i320
-#define TCG_TARGET_HAS_ext8s_i320
-#define TCG_TARGET_HAS_ext16s_i32   0
-#define TCG_TARGET_HAS_ext8u_i320
-#define TCG_TARGET_HAS_ext16u_i32   0
+#define TCG_TARGET_HAS_ext8s_i321
+#define TCG_TARGET_HAS_ext16s_i32   1
+#define TCG_TARGET_HAS_ext8u_i321
+#define TCG_TARGET_HAS_ext16u_i32   1
 #define TCG_TARGET_HAS_bswap16_i32  0
 #define TCG_TARGET_HAS_bswap32_i32  0
 #define TCG_TARGET_HAS_not_i32  0
@@ -138,14 +138,14 @@ typedef enum {
 #define TCG_TARGET_HAS_extract_i64  0
 #define TCG_TARGET_HAS_sextract_i64 0
 #define TCG_TARGET_HAS_extract2_i64 0
-#define TCG_TARGET_HAS_extrl_i64_i320
-#define TCG_TARGET_HAS_extrh_i64_i320
-#define TCG_TARGET_HAS_ext8s_i640
-#define TCG_TARGET_HAS_ext16s_i64   0
-#define TCG_TARGET_HAS_ext32s_i64   0
-#define TCG_TARGET_HAS_ext8u_i640
-#define TCG_TARGET_HAS_ext16u_i64   0
-#define TCG_TARGET_HAS_ext32u_i64   0
+#define TCG_TARGET_HAS_extrl_i64_i321
+#define TCG_TARGET_HAS_extrh_i64_i321
+#define TCG_TARGET_HAS_ext8s_i641
+#define TCG_TARGET_HAS_ext16s_i64   1
+#define TCG_TARGET_HAS_ext32s_i64   1
+#define TCG_TARGET_HAS_ext8u_i641
+#define TCG_TARGET_HAS_ext16u_i64   1
+#define TCG_TARGET_HAS_ext32u_i64   1
 #define TCG_TARGET_HAS_bswap16_i64  0
 #define TCG_TARGET_HAS_bswap32_i64  0
 #define TCG_TARGET_HAS_bswap64_i64  0
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3a8c52465b..25b58c7828 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -382,6 +382,36 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 }
 }
 
+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_andi(s, ret, arg, 0xff);
+}
+
+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15);
+}
+
+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31);
+}
+
+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_sext_b(s, ret, arg);
+}
+
+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_sext_h(s, ret, arg);
+}
+
+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_addi_w(s, ret, arg, 0);
+}
+
 /*
  * Entry-points
  */
@@ -391,6 +421,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const int const_args[TCG_MAX_OP_ARGS])
 {
 TCGArg a0 = args[0];
+TCGArg a1 = args[1];
 
 switch (opc) {
 case INDEX_op_mb:
@@ -401,6 +432,41 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
 break;
 
+case INDEX_op_ext8s_i32:
+case INDEX_op_ext8s_i64:
+tcg_out_ext8s(s, a0, a1);
+break;
+
+case INDEX_op_ext8u_i32:
+case INDEX_op_ext8u_i64:
+tcg_out_ext8u(s, a0, a1);
+break;
+
+case INDEX_op_ext16s_i32:
+case INDEX_op_ext16s_i64:
+tcg_out_ext16s(s, a0, a1);
+break;
+
+case INDEX_op_ext16u_i32:
+case INDEX_op_ext16u_i64:
+tcg_out_ext16u(s, a0, a1);
+break;
+
+case INDEX_op_ext32u_i64:
+case INDEX_op_extu_i32_i64:
+tcg_out_ext32u(s, a0, a1);
+break;
+
+case INDEX_op_ext32s_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_ext_i32_i64:
+tcg_out_ext32s(s, a0, a1);
+break;
+
+case INDEX_op_extrh_i64_i32:
+tcg_out_opc_srai_d(s, a0, a1, 32);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -414,6 +480,22 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case 

[PULL 20/31] tcg/loongarch64: Implement setcond ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-21-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 69 
 2 files changed, 70 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 367689c2e2..a2ec61237e 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -22,6 +22,7 @@ C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
+C_O1_I2(r, r, rZ)
 C_O1_I2(r, 0, rZ)
 C_O1_I2(r, rZ, rN)
 C_O1_I2(r, rZ, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index aedfc0df84..23c151f473 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -434,6 +434,66 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn 
opc,
 tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+TCGReg arg1, TCGReg arg2, bool c2)
+{
+TCGReg tmp;
+
+if (c2) {
+tcg_debug_assert(arg2 == 0);
+}
+
+switch (cond) {
+case TCG_COND_EQ:
+if (c2) {
+tmp = arg1;
+} else {
+tcg_out_opc_sub_d(s, ret, arg1, arg2);
+tmp = ret;
+}
+tcg_out_opc_sltui(s, ret, tmp, 1);
+break;
+case TCG_COND_NE:
+if (c2) {
+tmp = arg1;
+} else {
+tcg_out_opc_sub_d(s, ret, arg1, arg2);
+tmp = ret;
+}
+tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
+break;
+case TCG_COND_LT:
+tcg_out_opc_slt(s, ret, arg1, arg2);
+break;
+case TCG_COND_GE:
+tcg_out_opc_slt(s, ret, arg1, arg2);
+tcg_out_opc_xori(s, ret, ret, 1);
+break;
+case TCG_COND_LE:
+tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false);
+break;
+case TCG_COND_GT:
+tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false);
+break;
+case TCG_COND_LTU:
+tcg_out_opc_sltu(s, ret, arg1, arg2);
+break;
+case TCG_COND_GEU:
+tcg_out_opc_sltu(s, ret, arg1, arg2);
+tcg_out_opc_xori(s, ret, ret, 1);
+break;
+case TCG_COND_LEU:
+tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false);
+break;
+case TCG_COND_GTU:
+tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false);
+break;
+default:
+g_assert_not_reached();
+break;
+}
+}
+
 /*
  * Branch helpers
  */
@@ -815,6 +875,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_mod_du(s, a0, a1, a2);
 break;
 
+case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
+tcg_out_setcond(s, args[3], a0, a1, a2, c2);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -901,6 +966,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_ctz_i64:
 return C_O1_I2(r, r, rW);
 
+case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
+return C_O1_I2(r, r, rZ);
+
 case INDEX_op_deposit_i32:
 case INDEX_op_deposit_i64:
 /* Must deposit into the same register as input */
-- 
2.25.1




[PULL 26/31] tcg/loongarch64: Implement tcg_target_init

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-27-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 92a30b791a..19bfc135f6 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1604,3 +1604,30 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
 tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0);
 }
+
+static void tcg_target_init(TCGContext *s)
+{
+tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
+tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
+
+tcg_target_call_clobber_regs = ALL_GENERAL_REGS;
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9);
+
+s->reserved_regs = 0;
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
+}
-- 
2.25.1




[PULL 10/31] tcg/loongarch64: Implement goto_ptr

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-11-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h | 17 +
 tcg/loongarch64/tcg-target.c.inc | 15 +++
 2 files changed, 32 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-target-con-set.h

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
new file mode 100644
index 00..5cc4407367
--- /dev/null
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define LoongArch target-specific constraint sets.
+ *
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * Based on tcg/riscv/tcg-target-con-set.h
+ *
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index bb45ea0fcf..3a8c52465b 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -397,9 +397,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_mb(s, a0);
 break;
 
+case INDEX_op_goto_ptr:
+tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
 g_assert_not_reached();
 }
 }
+
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
+{
+switch (op) {
+case INDEX_op_goto_ptr:
+return C_O0_I1(r);
+
+default:
+g_assert_not_reached();
+}
+}
-- 
2.25.1




[PULL 16/31] tcg/loongarch64: Implement shl/shr/sar/rotl/rotr ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-17-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.h |  4 +-
 tcg/loongarch64/tcg-target.c.inc | 91 
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 2975e03127..42f8e28741 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -17,6 +17,7 @@
 C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
+C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 2fd2745b63..d1ded50cb0 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -96,7 +96,7 @@ typedef enum {
 #define TCG_TARGET_HAS_div_i32  0
 #define TCG_TARGET_HAS_rem_i32  0
 #define TCG_TARGET_HAS_div2_i32 0
-#define TCG_TARGET_HAS_rot_i32  0
+#define TCG_TARGET_HAS_rot_i32  1
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_extract_i32  1
 #define TCG_TARGET_HAS_sextract_i32 0
@@ -133,7 +133,7 @@ typedef enum {
 #define TCG_TARGET_HAS_div_i64  0
 #define TCG_TARGET_HAS_rem_i64  0
 #define TCG_TARGET_HAS_div2_i64 0
-#define TCG_TARGET_HAS_rot_i64  0
+#define TCG_TARGET_HAS_rot_i64  1
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_extract_i64  1
 #define TCG_TARGET_HAS_sextract_i64 0
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 39df2885b5..2895769e68 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -608,6 +608,85 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false);
 break;
 
+case INDEX_op_shl_i32:
+if (c2) {
+tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_sll_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_shl_i64:
+if (c2) {
+tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_sll_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_shr_i32:
+if (c2) {
+tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_srl_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_shr_i64:
+if (c2) {
+tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_srl_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_sar_i32:
+if (c2) {
+tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_sra_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_sar_i64:
+if (c2) {
+tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_sra_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_rotl_i32:
+/* transform into equivalent rotr/rotri */
+if (c2) {
+tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f);
+} else {
+tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
+tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0);
+}
+break;
+case INDEX_op_rotl_i64:
+/* transform into equivalent rotr/rotri */
+if (c2) {
+tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f);
+} else {
+tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
+tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0);
+}
+break;
+
+case INDEX_op_rotr_i32:
+if (c2) {
+tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_rotr_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_rotr_i64:
+if (c2) {
+tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_rotr_d(s, a0, a1, a2);
+}
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -657,6 +736,18 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
  */
 return C_O1_I2(r, r, rC);
 
+case INDEX_op_shl_i32:
+case INDEX_op_shl_i64:
+case INDEX_op_shr_i32:
+case INDEX_op_shr_i64:
+case INDEX_op_sar_i32:
+case INDEX_op_sar_i64:
+case INDEX_op_rotl_i32:
+case INDEX_op_rotl_i64:
+case INDEX_op_rotr_i32:
+case INDEX_op_rotr_i64:
+return C_O1_I2(r, r, ri);
+
 case INDEX_op_and_i32:
 case INDEX_op_and_i64:
 case INDEX_op_nor_i32:
-- 
2.25.1




[PULL 22/31] tcg/loongarch64: Implement simple load/store ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-23-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |   1 +
 tcg/loongarch64/tcg-target.c.inc | 131 +++
 2 files changed, 132 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index a2ec61237e..e54ca9b2de 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,6 +15,7 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O0_I2(rZ, r)
 C_O0_I2(rZ, rZ)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 151d3308ea..3d1d7c33c0 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -565,6 +565,73 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *arg)
 tcg_out_call_int(s, arg, false);
 }
 
+/*
+ * Load/store helpers
+ */
+
+static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
+ TCGReg addr, intptr_t offset)
+{
+intptr_t imm12 = sextreg(offset, 0, 12);
+
+if (offset != imm12) {
+intptr_t diff = offset - (uintptr_t)s->code_ptr;
+
+if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
+imm12 = sextreg(diff, 0, 12);
+tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
+if (addr != TCG_REG_ZERO) {
+tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr);
+}
+}
+addr = TCG_REG_TMP2;
+}
+
+switch (opc) {
+case OPC_LD_B:
+case OPC_LD_BU:
+case OPC_LD_H:
+case OPC_LD_HU:
+case OPC_LD_W:
+case OPC_LD_WU:
+case OPC_LD_D:
+case OPC_ST_B:
+case OPC_ST_H:
+case OPC_ST_W:
+case OPC_ST_D:
+tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12));
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is_32bit = type == TCG_TYPE_I32;
+tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2);
+}
+
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is_32bit = type == TCG_TYPE_I32;
+tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2);
+}
+
+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
+TCGReg base, intptr_t ofs)
+{
+if (val == 0) {
+tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
+return true;
+}
+return false;
+}
+
 /*
  * Entry-points
  */
@@ -913,6 +980,49 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_setcond(s, args[3], a0, a1, a2, c2);
 break;
 
+case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
+tcg_out_ldst(s, OPC_LD_B, a0, a1, a2);
+break;
+case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
+tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2);
+break;
+case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
+tcg_out_ldst(s, OPC_LD_H, a0, a1, a2);
+break;
+case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
+tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2);
+break;
+case INDEX_op_ld_i32:
+case INDEX_op_ld32s_i64:
+tcg_out_ldst(s, OPC_LD_W, a0, a1, a2);
+break;
+case INDEX_op_ld32u_i64:
+tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2);
+break;
+case INDEX_op_ld_i64:
+tcg_out_ldst(s, OPC_LD_D, a0, a1, a2);
+break;
+
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+tcg_out_ldst(s, OPC_ST_B, a0, a1, a2);
+break;
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+tcg_out_ldst(s, OPC_ST_H, a0, a1, a2);
+break;
+case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+tcg_out_ldst(s, OPC_ST_W, a0, a1, a2);
+break;
+case INDEX_op_st_i64:
+tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
@@ -927,6 +1037,15 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_goto_ptr:
 return C_O0_I1(r);
 
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+case INDEX_op_st32_i64:
+case INDEX_op_st_i32:
+case INDEX_op_st_i64:
+return C_O0_I2(rZ, r);
+
 case INDEX_op_brcond_i32:
 case INDEX_op_brcond_i64:
 return C_O0_I2(rZ, 

[PULL 15/31] tcg/loongarch64: Implement clz/ctz ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20211221054105.178795-16-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.h |  8 +++---
 tcg/loongarch64/tcg-target.c.inc | 42 
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index d958183020..2975e03127 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -18,4 +18,5 @@ C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, rU)
+C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 5303001653..2fd2745b63 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -120,8 +120,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i32  0
 #define TCG_TARGET_HAS_nand_i32 0
 #define TCG_TARGET_HAS_nor_i32  1
-#define TCG_TARGET_HAS_clz_i32  0
-#define TCG_TARGET_HAS_ctz_i32  0
+#define TCG_TARGET_HAS_clz_i32  1
+#define TCG_TARGET_HAS_ctz_i32  1
 #define TCG_TARGET_HAS_ctpop_i320
 #define TCG_TARGET_HAS_direct_jump  0
 #define TCG_TARGET_HAS_brcond2  0
@@ -156,8 +156,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i64  0
 #define TCG_TARGET_HAS_nand_i64 0
 #define TCG_TARGET_HAS_nor_i64  1
-#define TCG_TARGET_HAS_clz_i64  0
-#define TCG_TARGET_HAS_ctz_i64  0
+#define TCG_TARGET_HAS_clz_i64  1
+#define TCG_TARGET_HAS_ctz_i64  1
 #define TCG_TARGET_HAS_ctpop_i640
 #define TCG_TARGET_HAS_add2_i64 0
 #define TCG_TARGET_HAS_sub2_i64 0
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3b056dd358..39df2885b5 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -412,6 +412,28 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, 
TCGReg arg)
 tcg_out_opc_addi_w(s, ret, arg, 0);
 }
 
+static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
+   TCGReg a0, TCGReg a1, TCGReg a2,
+   bool c2, bool is_32bit)
+{
+if (c2) {
+/*
+ * Fast path: semantics already satisfied due to constraint and
+ * insn behavior, single instruction is enough.
+ */
+tcg_debug_assert(a2 == (is_32bit ? 32 : 64));
+/* all clz/ctz insns belong to DJ-format */
+tcg_out32(s, encode_dj_insn(opc, a0, a1));
+return;
+}
+
+tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1));
+/* a0 = a1 ? REG_TMP0 : a2 */
+tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1);
+tcg_out_opc_masknez(s, a0, a2, a1);
+tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
+}
+
 /*
  * Entry-points
  */
@@ -572,6 +594,20 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_revb_d(s, a0, a1);
 break;
 
+case INDEX_op_clz_i32:
+tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true);
+break;
+case INDEX_op_clz_i64:
+tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false);
+break;
+
+case INDEX_op_ctz_i32:
+tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true);
+break;
+case INDEX_op_ctz_i64:
+tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -632,6 +668,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 /* LoongArch reg-imm bitops have their imms ZERO-extended */
 return C_O1_I2(r, r, rU);
 
+case INDEX_op_clz_i32:
+case INDEX_op_clz_i64:
+case INDEX_op_ctz_i32:
+case INDEX_op_ctz_i64:
+return C_O1_I2(r, r, rW);
+
 case INDEX_op_deposit_i32:
 case INDEX_op_deposit_i64:
 /* Must deposit into the same register as input */
-- 
2.25.1




[PULL 12/31] tcg/loongarch64: Implement not/and/or/xor/nor/andc/orc ops

2021-12-21 Thread Richard Henderson
From: WANG Xuerui 

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211221054105.178795-13-...@xen0n.name>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  2 +
 tcg/loongarch64/tcg-target.h | 16 ++---
 tcg/loongarch64/tcg-target.c.inc | 88 
 3 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 7e459490ea..9ac24b8ad0 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -16,3 +16,5 @@
  */
 C_O0_I1(r)
 C_O1_I1(r, r)
+C_O1_I2(r, r, rC)
+C_O1_I2(r, r, rU)
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index a6d9e036fc..cc9aecc681 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -113,13 +113,13 @@ typedef enum {
 #define TCG_TARGET_HAS_ext16u_i32   1
 #define TCG_TARGET_HAS_bswap16_i32  0
 #define TCG_TARGET_HAS_bswap32_i32  0
-#define TCG_TARGET_HAS_not_i32  0
+#define TCG_TARGET_HAS_not_i32  1
 #define TCG_TARGET_HAS_neg_i32  0
-#define TCG_TARGET_HAS_andc_i32 0
-#define TCG_TARGET_HAS_orc_i32  0
+#define TCG_TARGET_HAS_andc_i32 1
+#define TCG_TARGET_HAS_orc_i32  1
 #define TCG_TARGET_HAS_eqv_i32  0
 #define TCG_TARGET_HAS_nand_i32 0
-#define TCG_TARGET_HAS_nor_i32  0
+#define TCG_TARGET_HAS_nor_i32  1
 #define TCG_TARGET_HAS_clz_i32  0
 #define TCG_TARGET_HAS_ctz_i32  0
 #define TCG_TARGET_HAS_ctpop_i320
@@ -149,13 +149,13 @@ typedef enum {
 #define TCG_TARGET_HAS_bswap16_i64  0
 #define TCG_TARGET_HAS_bswap32_i64  0
 #define TCG_TARGET_HAS_bswap64_i64  0
-#define TCG_TARGET_HAS_not_i64  0
+#define TCG_TARGET_HAS_not_i64  1
 #define TCG_TARGET_HAS_neg_i64  0
-#define TCG_TARGET_HAS_andc_i64 0
-#define TCG_TARGET_HAS_orc_i64  0
+#define TCG_TARGET_HAS_andc_i64 1
+#define TCG_TARGET_HAS_orc_i64  1
 #define TCG_TARGET_HAS_eqv_i64  0
 #define TCG_TARGET_HAS_nand_i64 0
-#define TCG_TARGET_HAS_nor_i64  0
+#define TCG_TARGET_HAS_nor_i64  1
 #define TCG_TARGET_HAS_clz_i64  0
 #define TCG_TARGET_HAS_ctz_i64  0
 #define TCG_TARGET_HAS_ctpop_i640
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 25b58c7828..d9508d5295 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -422,6 +422,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 {
 TCGArg a0 = args[0];
 TCGArg a1 = args[1];
+TCGArg a2 = args[2];
+int c2 = const_args[2];
 
 switch (opc) {
 case INDEX_op_mb:
@@ -467,6 +469,68 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_srai_d(s, a0, a1, 32);
 break;
 
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO);
+break;
+
+case INDEX_op_nor_i32:
+case INDEX_op_nor_i64:
+if (c2) {
+tcg_out_opc_ori(s, a0, a1, a2);
+tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO);
+} else {
+tcg_out_opc_nor(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_andc_i32:
+case INDEX_op_andc_i64:
+if (c2) {
+/* guaranteed to fit due to constraint */
+tcg_out_opc_andi(s, a0, a1, ~a2);
+} else {
+tcg_out_opc_andn(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_orc_i32:
+case INDEX_op_orc_i64:
+if (c2) {
+/* guaranteed to fit due to constraint */
+tcg_out_opc_ori(s, a0, a1, ~a2);
+} else {
+tcg_out_opc_orn(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_and_i32:
+case INDEX_op_and_i64:
+if (c2) {
+tcg_out_opc_andi(s, a0, a1, a2);
+} else {
+tcg_out_opc_and(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_or_i32:
+case INDEX_op_or_i64:
+if (c2) {
+tcg_out_opc_ori(s, a0, a1, a2);
+} else {
+tcg_out_opc_or(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
+if (c2) {
+tcg_out_opc_xori(s, a0, a1, a2);
+} else {
+tcg_out_opc_xor(s, a0, a1, a2);
+}
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -494,8 +558,32 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_extrl_i64_i32:
 case INDEX_op_extrh_i64_i32:
 case INDEX_op_ext_i32_i64:
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
 return C_O1_I1(r, r);
 
+case INDEX_op_andc_i32:
+case 

  1   2   3   >