Re: On integrating LoongArch EDK2 firmware into QEMU build process

2023-09-30 Thread WANG Xuerui

On 3/31/23 08:54, maobibo wrote:

Xuerui,

Thanks for your mail, it is a good suggestion. Now we are planing to move 
LoongArch uefi bios from edk2-platform to edk2 repo, so that uefi bios 
supporting LoongArch can be auto compiled and uploaded to qemu repo. Only that 
process is somwhat slow since lacking of hands, however we are doing this.


Pinging: a few months have passed, and it seems this work is stalled? 
Given the LoongArch Linux KVM support is about to land in v6.7, it may 
be time to prepare the firmware and QEMU side of things, so users would 
no longer have to manually acquire the firmware blobs whenever they fire 
up their VMs.




Regards
Bibo, Mao

在 2023/3/30 22:06, WANG Xuerui 写道:

Hi,

Recently there are reportedly increased general interest in trying out 
LoongArch on top of QEMU, among both end users and organizations; and the EDK2 
firmware port is fully upstreamed since the stable202211 version, and a build 
suitable for QEMU is already possible with Platform/Loongson/LoongArchQemuPkg 
in edk2-platforms. I think providing pre-built LoongArch firmware would make it 
much easier to dabble in system emulation, helping those users. (They currently 
have to pull a blob from yangxiaojuan/qemu-binary, and remember to pair certain 
version of QEMU with certain revision of the firmware blob. I'm also one of the 
users who can't remember which version to use, but I can always build my own; 
imagine the difficulty an end user would face!)

So I tried to add a LoongArch build to the list stored in roms/, but discovered 
that edk2-platforms seems not included, because all other platforms' EDK2 
packages are directly under the main edk2 repo.

The question is: is integrating a platform package from edk2-platforms okay 
under the current build system, so we can arrange to provide edk2-platforms 
also as a submodule and go ahead? Or do we (the LoongArch firmware community) 
have to change the code organization to make necessary parts available in the 
main edk2 repo?

CC-ing target/loongarch maintainers from Loongson too as you may have more 
information.







Re: [PATCH 0/7] tcg/loongarch64: Improvements for 128-bit load/store

2023-09-30 Thread WANG Xuerui

On 9/30/23 10:13, Richard Henderson wrote:

Ping.

r~

On 9/16/23 15:01, Richard Henderson wrote:

For tcg generated code, use new registers with load so that we never
overlap the input address, so that we can simplify address build for
64-bit user-only.

For tcg out-of-line code, implement the host/ headers to for atomic 
128-bit

load and store, reducing the cases for which we must raise EXCP_ATOMIC.


r~

Based-on: 20230916171223.521545-1-richard.hender...@linaro.org
("[PULL v2 00/39] tcg patch queue")

Richard Henderson (7):
   tcg: Add C_N2_I1
   tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128
   util: Add cpuinfo for loongarch64
   tcg/loongarch64: Use cpuinfo.h
   host/include/loongarch64: Add atomic16 load and store
   accel/tcg: Remove redundant case in store_atom_16
   accel/tcg: Fix condition for store_atom_insert_al16

  .../include/loongarch64/host/atomic128-ldst.h | 52 +++
  host/include/loongarch64/host/cpuinfo.h   | 21 
  .../loongarch64/host/load-extract-al16-al8.h  | 39 ++
  .../loongarch64/host/store-insert-al16.h  | 12 +
  tcg/loongarch64/tcg-target-con-set.h  |  2 +-
  tcg/loongarch64/tcg-target.h  |  8 +--
  accel/tcg/cputlb.c    |  2 +-
  tcg/tcg.c |  5 ++
  util/cpuinfo-loongarch.c  | 35 +
  accel/tcg/ldst_atomicity.c.inc    | 14 ++---
  tcg/loongarch64/tcg-target.c.inc  | 25 +
  util/meson.build  |  2 +
  12 files changed, 189 insertions(+), 28 deletions(-)
  create mode 100644 host/include/loongarch64/host/atomic128-ldst.h
  create mode 100644 host/include/loongarch64/host/cpuinfo.h
  create mode 100644 
host/include/loongarch64/host/load-extract-al16-al8.h

  create mode 100644 host/include/loongarch64/host/store-insert-al16.h
  create mode 100644 util/cpuinfo-loongarch.c


Sorry for the delay; I've skimmed through the series and tested on 
Loongson 3C5000L hardware, so


Reviewed-by: WANG Xuerui 



Re: [PATCH v3 2/6] target/loongarch: Add loongarch32 cpu la132

2023-08-07 Thread WANG Xuerui

Hi,

On 2023/8/7 17:45, Jiajie Chen wrote:

Add la132 as a loongarch32 cpu type and allow virt machine to be used
with la132 instead of la464.

Signed-off-by: Jiajie Chen 
---
  hw/loongarch/virt.c|  5 -
  target/loongarch/cpu.c | 41 +
  target/loongarch/cpu.h | 11 +++
  3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e19b042ce8..af15bf5aaa 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine)
  cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
  }
  
-if (!strstr(cpu_model, "la464")) {

-error_report("LoongArch/TCG needs cpu type la464");
-exit(1);
-}
-
  if (ram_size < 1 * GiB) {
  error_report("ram_size must be greater than 1G.");
  exit(1);
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index ad93ecac92..d31efe86da 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -362,6 +362,8 @@ static void loongarch_la464_initfn(Object *obj)
  CPULoongArchState *env = >env;
  int i;
  
+env->mode = LA64;

+
  for (i = 0; i < 21; i++) {
  env->cpucfg[i] = 0x0;
  }
@@ -439,6 +441,20 @@ static void loongarch_la464_initfn(Object *obj)
  env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
  }
  
+static void loongarch_la132_initfn(Object *obj)

+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = >env;
+
+env->mode = LA32;
+
+cpu->dtb_compatible = "loongarch,Loongson-3C103";


"3C103"? I assume you want something like "1C300" or "1Axxx", at least 
something prefixed with "1"...




Re: [PATCH v4 36/57] tcg/loongarch64: Assert the host supports unaligned accesses

2023-05-05 Thread WANG Xuerui

Hi,

On 2023/5/3 15:06, Richard Henderson wrote:

This should be true of all server class loongarch64.

And desktop-class (i.e. all Loongson-3 series).


Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target.c.inc | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index e651ec5c71..ccc13ffdb4 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -30,6 +30,7 @@
   */
  
  #include "../tcg-ldst.c.inc"

+#include 
  
  #ifdef CONFIG_DEBUG_TCG

  static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@@ -1674,6 +1675,11 @@ static void tcg_target_qemu_prologue(TCGContext *s)
  
  static void tcg_target_init(TCGContext *s)

  {
+unsigned long hwcap = qemu_getauxval(AT_HWCAP);
+
+/* All server class loongarch have UAL; only embedded do not. */
+assert(hwcap & HWCAP_LOONGARCH_UAL);
+
It is a bit worrying that a future SoC (the octa-core Loongson 2K3000) 
might get used for light desktop use cases (e.g. laptops) where QEMU is 
arguably relevant, but it's currently unclear whether its LA364 
micro-architecture will have UAL. The Loongson folks may have more to share.

  tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
  tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
  




On integrating LoongArch EDK2 firmware into QEMU build process

2023-03-30 Thread WANG Xuerui

Hi,

Recently there are reportedly increased general interest in trying out 
LoongArch on top of QEMU, among both end users and organizations; and 
the EDK2 firmware port is fully upstreamed since the stable202211 
version, and a build suitable for QEMU is already possible with 
Platform/Loongson/LoongArchQemuPkg in edk2-platforms. I think providing 
pre-built LoongArch firmware would make it much easier to dabble in 
system emulation, helping those users. (They currently have to pull a 
blob from yangxiaojuan/qemu-binary, and remember to pair certain version 
of QEMU with certain revision of the firmware blob. I'm also one of the 
users who can't remember which version to use, but I can always build my 
own; imagine the difficulty an end user would face!)


So I tried to add a LoongArch build to the list stored in roms/, but 
discovered that edk2-platforms seems not included, because all other 
platforms' EDK2 packages are directly under the main edk2 repo.


The question is: is integrating a platform package from edk2-platforms 
okay under the current build system, so we can arrange to provide 
edk2-platforms also as a submodule and go ahead? Or do we (the LoongArch 
firmware community) have to change the code organization to make 
necessary parts available in the main edk2 repo?


CC-ing target/loongarch maintainers from Loongson too as you may have 
more information.





[PATCH] linux-user: Add support for LoongArch64's old world ABI

2023-01-23 Thread WANG Xuerui
From: WANG Xuerui 

This patch adds a "loongarch64ow-linux-user" target and a
corresponding "qemu-loongarch64ow" binary, for supporting user-mode
emulation of old-world LoongArch applications in the wild.

Although the old-world LoongArch is already being (slowly) phased out,
there are already a number of deployments (mainly as a result of
LoongArch's early commercial growth), whose migration path is something
software developers have to care about. Support for user-mode emulation
in addition to system-level emulation would help development of such
migration & compatibility solutions.

The differences we have to care about are:

- TARGET_NSIG: 64 for new-world, 128 for old-world
- System calls: fstat, newfstatat, getrlimit and setrlimit only present
  on old-world

Other incompatibilities exist, but they are irrelevant to emulators like
QEMU, as these are entirely contained within the particular firmware
image or sysroot in use.

Corresponding binfmt_misc magic has been updated to allow somewhat
proper classification of LoongArch executables based on the object ABI
version bitfield [1] in the ELF header's e_flags field. We make the
assumption that all old-world binaries are compiled with an older
toolchain that produce v0 binaries, and that all new-world users have
migrated to object ABI v1 by now -- the initial new-world userbase is
small and technical enough that anyone who has not migrated by now is
simply advised to rebuild world or reinstall.

As for why this cannot be done within one binary: currently TARGET_NSIG
is a compile-time constant, hence it is not currently possible for us
to implement an allegedly more elegant solution, of checking the
.note.ABI-tag section (then falling back to e_flags heuristics if the
optional section is absent).

[1]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version

Signed-off-by: WANG Xuerui 
---

Tested by successfully emulating a Loongnix chroot, running old-world
LoongArch apps such as the bundled Kingsoft Office 2019, in addition to
common CLI utilities and some of the MATE apps included in the distro's
live ISO.

 configs/targets/loongarch64ow-linux-user.mak |   4 +
 linux-user/loongarch64/syscall_base_nr.h | 312 ++
 linux-user/loongarch64/syscall_nr.h  | 316 +--
 linux-user/syscall_defs.h|   9 +-
 scripts/gensyscalls.sh   |   2 +-
 scripts/qemu-binfmt-conf.sh  |  12 +-
 6 files changed, 340 insertions(+), 315 deletions(-)
 create mode 100644 configs/targets/loongarch64ow-linux-user.mak
 create mode 100644 linux-user/loongarch64/syscall_base_nr.h

diff --git a/configs/targets/loongarch64ow-linux-user.mak 
b/configs/targets/loongarch64ow-linux-user.mak
new file mode 100644
index 00..41eb8c16a7
--- /dev/null
+++ b/configs/targets/loongarch64ow-linux-user.mak
@@ -0,0 +1,4 @@
+# Default configuration for loongarch64-linux-user
+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch
+TARGET_ABI_LOONGARCH64_OW=y
diff --git a/linux-user/loongarch64/syscall_base_nr.h 
b/linux-user/loongarch64/syscall_base_nr.h
new file mode 100644
index 00..f84434bfa2
--- /dev/null
+++ b/linux-user/loongarch64/syscall_base_nr.h
@@ -0,0 +1,312 @@
+/*
+ * This file contains the system call numbers.
+ * Do not modify.
+ * This file is generated by scripts/gensyscalls.sh
+ */
+#ifndef LINUX_USER_LOONGARCH_SYSCALL_BASE_NR_H
+#define LINUX_USER_LOONGARCH_SYSCALL_BASE_NR_H
+
+#define TARGET_NR_io_setup 0
+#define TARGET_NR_io_destroy 1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_io_getevents 4
+#define TARGET_NR_setxattr 5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr 8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr 12
+#define TARGET_NR_flistxattr 13
+#define TARGET_NR_removexattr 14
+#define TARGET_NR_lremovexattr 15
+#define TARGET_NR_fremovexattr 16
+#define TARGET_NR_getcwd 17
+#define TARGET_NR_lookup_dcookie 18
+#define TARGET_NR_eventfd2 19
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_fcntl 25
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+#define TARGET_NR_ioctl 29
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+#define TARGET_NR_flock 32
+#define TARGET_NR_mknodat 33
+#define TARGET_NR_mkdirat 34
+#define TARGET_NR_unlinkat 35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat 37
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+#define TARGET_NR_nfsservctl 42
+#define TARGET_NR_statfs 43
+#define TARGET_NR_fstatfs 44
+#define TARGET_NR_truncate 45
+#defin

Re: [PATCH] linux-user: Add support for LoongArch64's old world ABI

2023-01-23 Thread WANG Xuerui

On 1/23/23 18:47, Peter Maydell wrote:

On Mon, 23 Jan 2023 at 10:27, WANG Xuerui  wrote:


From: WANG Xuerui 

This patch adds a "loongarch64ow-linux-user" target and a
corresponding "qemu-loongarch64ow" binary, for supporting user-mode
emulation of old-world LoongArch applications in the wild.

Although the old-world LoongArch is already being (slowly) phased out,
there are already a number of deployments (mainly as a result of
LoongArch's early commercial growth), whose migration path is something
software developers have to care about. Support for user-mode emulation
in addition to system-level emulation would help development of such
migration & compatibility solutions.


Is this 'old-world' ABI supported by the upstream Linux kernel?
I can't see signs of it from a quick grep. If it isn't, then
I'm not sure if we should support it in QEMU user-mode emulation.
We've always set "upstream Linux" as our definition of what the
official ABI and featureset is for usermode emulation.


No, the old-world is not, and will not be, supported by upstream Linux, 
as it is strictly the premature state of this architecture only born for 
commercial reasons.


After sending the patch I've discussed with several other maintainers of 
various LoongArch ports, and it seems even Loongson the corporation 
itself is seeing to completely abandon old-world development in favor of 
a 100% new world future (which is even more courageous than me, an 
unaffiliated hobbyist user). Given the current old-world deployments all 
have commercial support, it's probably best to leave the migration work 
for them and keep upstream clean of any such legacy.


So I'm dropping this patch now, and thanks for the feedback!



Re: [PATCH v2 10/10] tcg/loongarch64: Reorg goto_tb implementation

2023-01-23 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

The old implementation replaces two insns, swapping between

 b   
 nop
and
 pcaddu18i tmp, 
 jirl  zero, tmp,  & 0x

There is a race condition in which a thread could be stopped at
the jirl, i.e. with the top of the address loaded, and when
restarted we have re-linked to a different TB, so that the top
half no longer matches the bottom half.

Note that while we never directly re-link to a different TB, we
can link, unlink, and link again all while the stopped thread
remains stopped.

The new implementation replaces only one insn, swapping between

 b   
and
 pcadd   tmp, 

falling through to load the address from tmp, and branch.

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target.h |  7 +---
  tcg/loongarch64/tcg-target.c.inc | 72 ++--
  2 files changed, 33 insertions(+), 46 deletions(-)


I've tested this on my 3A5000 box and things seem to work, thanks.

Reviewed-by: WANG Xuerui 




Re: [PATCH v2 07/10] tcg/loongarch64: Improve setcond expansion

2023-01-23 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Split out a helper function, tcg_out_setcond_int, which
does not always produce the complete boolean result, but
returns a set of flags to do so.

Accept all int32_t as constant input, so that LE/GT can
adjust the constant to LT.

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target.c.inc | 165 +--
  1 file changed, 115 insertions(+), 50 deletions(-)


Reviewed-by: WANG Xuerui 

Thanks!




Re: [PATCH v2 06/10] tcg/loongarch64: Introduce tcg_out_addi

2023-01-23 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Adjust the constraints to allow any int32_t for immediate
addition.  Split immediate adds into addu16i + addi, which
covers quite a lot of the immediate space.  For the hole in
the middle, load the constant into TMP0 instead.

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target-con-set.h |  4 +-
  tcg/loongarch64/tcg-target-con-str.h |  2 +-
  tcg/loongarch64/tcg-target.c.inc | 57 
  3 files changed, 53 insertions(+), 10 deletions(-)


I've checked some generated code and this indeed benefits.

Reviewed-by: WANG Xuerui 




Re: [PATCH v2 01/10] target/loongarch: Enable the disassembler for host tcg

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Reuse the decodetree based disassembler from
target/loongarch/ for tcg/loongarch64/.

The generation of decode-insns.c.inc into ./libcommon.fa.p/ could
eventually result in conflict, if any other host requires the same
trick, but this is good enough for now.

Signed-off-by: Richard Henderson 
---
  disas.c  | 2 ++
  target/loongarch/meson.build | 3 ++-
  2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/disas.c b/disas.c
index 3b31315f40..c9fa38e6d7 100644
--- a/disas.c
+++ b/disas.c
@@ -198,6 +198,8 @@ static void initialize_debug_host(CPUDebug *s)
  s->info.cap_insn_split = 6;
  #elif defined(__hppa__)
  s->info.print_insn = print_insn_hppa;
+#elif defined(__loongarch64)
This could just be `__loongarch__` because both LA32 and LA64 share the 
same encoding, so although LA32 userland isn't quite there yet it 
wouldn't do any harm.

+s->info.print_insn = print_insn_loongarch;
  #endif
  }
  
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build

index 6376f9e84b..690633969f 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -3,7 +3,6 @@ gen = decodetree.process('insns.decode')
  loongarch_ss = ss.source_set()
  loongarch_ss.add(files(
'cpu.c',
-  'disas.c',
  ))
  loongarch_tcg_ss = ss.source_set()
  loongarch_tcg_ss.add(gen)
@@ -24,6 +23,8 @@ loongarch_softmmu_ss.add(files(
'iocsr_helper.c',
  ))
  
+common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen])

+
  loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
  
  target_arch += {'loongarch': loongarch_ss}


Apart from the minor suggestion above,

Reviewed-by: WANG Xuerui 

Thanks!




Re: [PATCH v2 00/10] tcg/loongarch64: Reorg goto_tb and cleanups

2023-01-22 Thread WANG Xuerui

Hi,

On 1/18/23 09:11, Richard Henderson wrote:

Based-on: 20230117231051.35-1-richard.hender...@linaro.org
("[PULL 00/22] tcg patch queue")

Includes:
   * Disassembler from target/loongarch/.
   * Improvements to movi by Rui Wang, with minor tweaks.
   * Improvements to setcond.
   * Implement movcond.
   * Fix the same goto_tb bug that affected some others.


r~


Richard Henderson (9):
   target/loongarch: Enable the disassembler for host tcg
   target/loongarch: Disassemble jirl properly
   target/loongarch: Disassemble pcadd* addresses
   tcg/loongarch64: Update tcg-insn-defs.c.inc
   tcg/loongarch64: Introduce tcg_out_addi
   tcg/loongarch64: Improve setcond expansion
   tcg/loongarch64: Implement movcond
   tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst
   tcg/loongarch64: Reorg goto_tb implementation

Rui Wang (1):
   tcg/loongarch64: Optimize immediate loading

  tcg/loongarch64/tcg-target-con-set.h  |   5 +-
  tcg/loongarch64/tcg-target-con-str.h  |   2 +-
  tcg/loongarch64/tcg-target.h  |  11 +-
  disas.c   |   2 +
  target/loongarch/disas.c  |  39 +-
  .../loongarch/insn_trans/trans_branch.c.inc   |   2 +-
  target/loongarch/insns.decode |   3 +-
  target/loongarch/meson.build  |   3 +-
  tcg/loongarch64/tcg-insn-defs.c.inc   |  10 +-
  tcg/loongarch64/tcg-target.c.inc  | 364 --
  10 files changed, 300 insertions(+), 141 deletions(-)
  mode change 100644 => 100755 tcg/loongarch64/tcg-insn-defs.c.inc

Sorry for the late review; I was focusing more on LLVM and day job these 
days. I've reviewed some of these and will take a look at the rest (and 
test all of them on native HW) tonight. Thanks very much for all the 
refactoring!




Re: [PATCH v2 05/10] tcg/loongarch64: Update tcg-insn-defs.c.inc

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Regenerate with ADDU16I included:

$ cd loongarch-opcodes/scripts/go
$ go run ./genqemutcgdefs > $QEMU/tcg/loongarch64/tcg-insn-defs.c.inc

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-insn-defs.c.inc | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)
  mode change 100644 => 100755 tcg/loongarch64/tcg-insn-defs.c.inc

diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc 
b/tcg/loongarch64/tcg-insn-defs.c.inc
old mode 100644
new mode 100755
index d162571856..b5bb0c5e73
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
@@ -4,7 +4,7 @@
   *
   * This file is auto-generated by genqemutcgdefs from
   * https://github.com/loongson-community/loongarch-opcodes,
- * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4.
+ * from commit 25ca7effe9d88101c1cf96c4005423643386d81f.
   * DO NOT EDIT.
   */
  
@@ -74,6 +74,7 @@ typedef enum {

  OPC_ANDI = 0x0340,
  OPC_ORI = 0x0380,
  OPC_XORI = 0x03c0,
+OPC_ADDU16I_D = 0x1000,
  OPC_LU12I_W = 0x1400,
  OPC_CU32I_D = 0x1600,
  OPC_PCADDU2I = 0x1800,
@@ -710,6 +711,13 @@ tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, 
uint32_t uk12)
  tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12));
  }
  
+/* Emits the `addu16i.d d, j, sk16` instruction.  */

+static void __attribute__((unused))
+tcg_out_opc_addu16i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16)
+{
+tcg_out32(s, encode_djsk16_insn(OPC_ADDU16I_D, d, j, sk16));
+}
+
  /* Emits the `lu12i.w d, sj20` instruction.  */
  static void __attribute__((unused))
  tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20)


Reviewed-by: WANG Xuerui 




Re: [PATCH v2 08/10] tcg/loongarch64: Implement movcond

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

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 | 33 
  3 files changed, 36 insertions(+), 2 deletions(-)


Reviewed-by: WANG Xuerui 




Re: [PATCH v2 04/10] tcg/loongarch64: Optimize immediate loading

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

From: Rui Wang 

diff:
   Imm Before  After
   addi.w  rd, zero, 0 addi.w  rd, zero, 0
   lu52i.d rd, zero, 0
   f800lu12i.w rd, -1  addi.w  rd, zero, -2048
   ori rd, rd, 2048lu32i.d rd, 0
   lu32i.d rd, 0
   ...

Signed-off-by: Rui Wang 
Message-Id: <20221107144713.845550-1-wang...@loongson.cn>
Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target.c.inc | 35 +++-
  1 file changed, 12 insertions(+), 23 deletions(-)


Reviewed-by: WANG Xuerui 

Thanks!




Re: [PATCH v2 02/10] target/loongarch: Disassemble jirl properly

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

While jirl shares the same instruction format as bne etc,
it is not assembled the same.  In particular, rd is printed
first not second and the immediate is not pc-relative.

Decode into the arg_rr_i structure, which prints correctly.
This changes the "offs" member to "imm", to update translate.

Signed-off-by: Richard Henderson 
---
  target/loongarch/disas.c   | 2 +-
  target/loongarch/insn_trans/trans_branch.c.inc | 2 +-
  target/loongarch/insns.decode  | 3 ++-
  3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 858dfcc53a..7cffd853ec 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -628,7 +628,7 @@ INSN(beqz, r_offs)
  INSN(bnez, r_offs)
  INSN(bceqz,c_offs)
  INSN(bcnez,c_offs)
-INSN(jirl, rr_offs)
+INSN(jirl, rr_i)
  INSN(b,offs)
  INSN(bl,   offs)
  INSN(beq,  rr_offs)
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index 65dbdff41e..a860f7e733 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -23,7 +23,7 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
  TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
  TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
  
-tcg_gen_addi_tl(cpu_pc, src1, a->offs);

+tcg_gen_addi_tl(cpu_pc, src1, a->imm);
  tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
  gen_set_gpr(a->rd, dest, EXT_NONE);
  tcg_gen_lookup_and_goto_ptr();
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 3fdc6e148c..de7b8f0f3c 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -67,6 +67,7 @@
  @rr_ui12  .. imm:12 rj:5 rd:5_i
  @rr_i14s2    .. rj:5 rd:5_i imm=%i14s2
  @rr_i16  .. imm:s16 rj:5 rd:5_i
+@rr_i16s2  ..   rj:5 rd:5_i imm=%offs16
  @hint_r_i12    .. imm:s12 rj:5 hint:5_r_i
  @rrr_sa2p1  ... .. rk:5 rj:5 rd:5_sa  sa=%sa2p1
  @rrr_sa2  ... sa:2 rk:5 rj:5 rd:5_sa
@@ -444,7 +445,7 @@ beqz0100 00  . . 
@r_offs21
  bnez0100 01  . . @r_offs21
  bceqz   0100 10  00 ... .@c_offs21
  bcnez   0100 10  01 ... .@c_offs21
-jirl0100 11  . . @rr_offs16
+jirl0100 11  . . @rr_i16s2
  b   0101 00 ..   @offs26
  bl  0101 01 ..   @offs26
  beq 0101 10  . ..... @rr_offs16


Reviewed-by: WANG Xuerui 

Thanks for the catch!




Re: [PATCH v2 09/10] tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Take the w^x split into account when computing the
pc-relative distance to an absolute pointer.

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-target.c.inc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 29d75c80eb..d6926bdb83 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -702,7 +702,7 @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, 
TCGReg data,
  intptr_t imm12 = sextreg(offset, 0, 12);
  
  if (offset != imm12) {

-intptr_t diff = offset - (uintptr_t)s->code_ptr;
+intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
  
  if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {

  imm12 = sextreg(diff, 0, 12);


Reviewed-by: WANG Xuerui 

Thanks for the catch!




Re: [PATCH v2 03/10] target/loongarch: Disassemble pcadd* addresses

2023-01-22 Thread WANG Xuerui

On 1/18/23 09:11, Richard Henderson wrote:

Print both the raw field and the resolved pc-relative
address, as we do for branches.

Signed-off-by: Richard Henderson 
---
  target/loongarch/disas.c | 37 +
  1 file changed, 33 insertions(+), 4 deletions(-)


Reviewed-by: WANG Xuerui 

Thanks!




Re: [PATCH 3/8] tcg/loongarch64: Update tcg-insn-defs.c.inc

2022-12-15 Thread WANG Xuerui

On 12/15/22 23:51, Richard Henderson wrote:

On 12/14/22 23:50, Philippe Mathieu-Daudé wrote:

On 6/12/22 05:40, Richard Henderson wrote:

Regenerate with ADDU16I included.

Signed-off-by: Richard Henderson 
---
  tcg/loongarch64/tcg-insn-defs.c.inc | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc 
b/tcg/loongarch64/tcg-insn-defs.c.inc

index d162571856..c3c8669b4b 100644
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
@@ -4,7 +4,7 @@
   *
   * This file is auto-generated by genqemutcgdefs from
   * https://github.com/loongson-community/loongarch-opcodes,
- * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4.


Odd, addu16i.d is present since 3d057a6, so was already in 961f0c6.


It wasn't marked "qemu", so the generator didn't emit ...


@@ -74,6 +74,7 @@ typedef enum {
  OPC_ANDI = 0x0340,
  OPC_ORI = 0x0380,
  OPC_XORI = 0x03c0,
+    OPC_ADDU16I_D = 0x1000,
  OPC_LU12I_W = 0x1400,
  OPC_CU32I_D = 0x1600,
  OPC_PCADDU2I = 0x1800,
@@ -710,6 +711,13 @@ tcg_out_opc_xori(TCGContext *s, TCGReg d, 
TCGReg j, uint32_t uk12)

  tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12));
  }
+/* Emits the `addu16i.d d, j, sk16` instruction.  */
+static void __attribute__((unused))
+tcg_out_opc_addu16i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16)
+{
+    tcg_out32(s, encode_djsk16_insn(OPC_ADDU16I_D, d, j, sk16));
+}


... all this.

Ah. Sorry for the late reply, I've been busy with Gentoo and LLVM mostly 
these days (apart from the day job more demanding than ever, due to 
end-of-year and a bit too much slack doing LoongArch work instead ;-).


So do you need the addu16i.d marked as @qemu now? I can push the change 
into loongarch-opcodes tomorrow if so wanted. Of course it's probably 
better to maintain the used opcodes list in qemu's repo, let me refactor 
this after I somehow crawl out of the pile of day job...





Re: [PATCH v4] tcg/loongarch64: Add direct jump support

2022-10-20 Thread WANG Xuerui



On October 21, 2022 6:42:58 AM GMT+08:00, Richard Henderson 
 wrote:
>Fixed a minor nit:
>
>> +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
>> +  uintptr_t jmp_rw, uintptr_t addr)
>> +{
>> +tcg_insn_unit i1, i2;
>> +ptrdiff_t upper, lower;
>> +ptrdiff_t offset = (ptrdiff_t)(addr - jmp_rx) >> 2;
>> +
>> +if (offset == sextreg(offset, 0, 26)) {
>> +i1 = encode_sd10k16_insn(OPC_B, offset);
>> +i2 = NOP;
>> +} else {
>> +tcg_debug_assert(offset == sextreg(offset, 0, 36));
>
>This assert is smaller...
>
>> +/*
>> + * PCADDU18I + JIRL sequence can give 20 + 16 + 2 = 38 bits
>> + * signed offset, which is +/- 128 GiB.
>> + */
>> +#define MAX_CODE_GEN_BUFFER_SIZE  (128 * GiB)
>
>... than the correct calculation here.

Actually no... the offset above is pre-shifted so 36 is exactly 20 (pcaddu18i) 
+ 16 (jirl). The LoongArch assembly gotchas hit hard...



Re: [PATCH v3] tcg/loongarch64: Add direct jump support

2022-10-15 Thread WANG Xuerui
8_i32 0
@@ -166,7 +166,6 @@ typedef enum {
  #define TCG_TARGET_HAS_muluh_i641
  #define TCG_TARGET_HAS_mulsh_i641
  
-/* not defined -- call should be eliminated at compile time */

  void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
  
  #define TCG_TARGET_DEFAULT_MO (0)


With the nits addressed,

Reviewed-by: WANG Xuerui 





Re: [PATCH v4] tcg/loongarch64: Add direct jump support

2022-10-15 Thread WANG Xuerui

On 10/15/22 17:27, Qi Hu wrote:

Similar to the ARM64, LoongArch has PC-relative instructions such as
PCADDU18I. These instructions can be used to support direct jump for
LoongArch. Additionally, if instruction "B offset" can cover the target
address(target is within ±128MB range), a single "B offset" plus a nop
will be used by "tb_target_set_jump_target".

Cc: Richard Henderson 
Signed-off-by: Qi Hu 
---
Changes since v3:
- Fix the offset check error which is pointed by WANG Xuerui.
- Use TMP0 instead of T0.
- Remove useless block due to direct jump support.
- Add some assertions.
---
  tcg/loongarch64/tcg-target.c.inc | 48 +---
  tcg/loongarch64/tcg-target.h |  9 --
  2 files changed, 50 insertions(+), 7 deletions(-)


Richard may want to double-check for restoring his R-b, but this looks 
good to me now. Thanks!


Reviewed-by: WANG Xuerui 




Re: [PATCH 2/2] tcg/loongarch64: Add direct jump support

2022-10-12 Thread WANG Xuerui


On 2022/10/12 19:34, WANG Xuerui wrote:

+    tcg_insn_unit i1, i2;
+
+    ptrdiff_t offset = addr - jmp_rx;
+
+    if (offset == sextreg(offset, 0, 28)) {
+    i1 = OPC_B | ((offset >> 18) & 0x3ff) | ((offset << 8) & 
0x3fffc00);
Use encode_sd10k16_insn instead. No need to juggle the bits yourself 
and you get nice range assertion for free.
+    i2 = NOP; 


One more thing. I think there's a certain trend of making sure 
potentially bad things don't happen and stopping speculative insn 
fetch/execution by making the NOP here a BREAK instead. Although I'm not 
sure if LoongArch or TCG is affected by the various speculation 
vulnerabilities out there, to any degree, it might not hurt to just make 
it a BREAK? Performance shouldn't get affected in any way but one could 
probably sleep better with a guaranteed termination of execution flow 
after the B.


And you should change the "tcg_out32(s, NOP)" some lines above into just 
a "tcg_out_andi(s, 0, 0, 0)". This way you wouldn't have to define a NOP 
constant at all... Or, maybe better, make a "tcg_out_nop" helper right 
after the insn-defs include and after the "TCG intrinsics" section (it 
isn't one, but there isn't a better place), then use it here, so you get 
to include some more comments while still not having to define a NOP. Like:


static void tcg_out_nop(TCGContext *s)
{
/* Conventional NOP in LoongArch is `andi zero, zero, 0`.  */
tcg_out_opc_andi(s, 0, 0, 0);
}


Re: [PATCH 2/2] tcg/loongarch64: Add direct jump support

2022-10-12 Thread WANG Xuerui

Hi,

Thanks for the improvement! Some room for improvement though...

On 2022/10/12 17:13, Qi Hu wrote:

Similar to the ARM64, LoongArch has PC-relative instructions such as
PCADDU18I. These instructions can be used to support direct jump for
LoongArch. Additionally, if instruction "B offset" can cover the target
address, "tb_target_set_jmp_target" will only patch the "B offset".


"if the target is within +/- 28 bits range, a single "B offset" plus a 
nop will be used instead" might sound better?




Signed-off-by: Qi Hu 
---
  tcg/loongarch64/tcg-insn-defs.c.inc |  3 ++
  tcg/loongarch64/tcg-target.c.inc| 49 ++---
  tcg/loongarch64/tcg-target.h|  2 +-
  3 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc 
b/tcg/loongarch64/tcg-insn-defs.c.inc
index d162571856..f5869c6bb1 100644
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
@@ -112,6 +112,9 @@ typedef enum {
  OPC_BLE = 0x6400,
  OPC_BGTU = 0x6800,
  OPC_BLEU = 0x6c00,
+/* pseudo-instruction */
+NOP = 0x0340,
+


You certainly saw the big fat comment block saying the file was 
auto-generated and thus shouldn't be touched, didn't you? ;-)


I saw your need for a NOP constant later though, and you can instead add 
`#define OPC_NOP OPC_ANDI` in tcg-target.c.inc, just below the include 
of tcg-insn-defs.c.inc.



  } LoongArchInsn;
  
  static int32_t __attribute__((unused))

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index f5a214a17f..3a7b1df081 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1058,11 +1058,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
  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);
+if (s->tb_jmp_insn_offset != NULL) {
+/* TCG_TARGET_HAS_direct_jump */
+/* Ensure that PCADD+JIRL are 8-byte aligned so that an atomic
+   write can be used to patch the target address. */
There isn't a "PCADD" in LoongArch, and it's possible for the 2 insns to 
be "B + NOP" as well. So better reword a bit like "Ensure that the 
8-byte direct jump fragment is aligned ..." (and add another space after 
the period at the end of the sentence).

+if ((uintptr_t)s->code_ptr & 7) {
+tcg_out32(s, NOP);
+}
+s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+/* actual branch destination will be patched by
+   tb_target_set_jmp_target later. */
Either make it a proper sentence by title-casing "actual" and adding 
another space after the trailing period, or remove the period.

+tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, 0);
+tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+} else {
+/* !TCG_TARGET_HAS_direct_jump */
+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);
+}
We unconditionally support the direct jump method after the change, so 
do we need to retain this block any more? Note the aarch64 port 
currently does the same (declaring unconditional support for direct 
jumps but keeping both code paths), if we want to remove this code path 
then you may want to remove the aarch64 one respectively too.

  set_jmp_reset_offset(s, a0);
  break;
  
@@ -1708,6 +1721,32 @@ static void tcg_target_init(TCGContext *s)

  tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
  }
  
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,

+  uintptr_t jmp_rw, uintptr_t addr)
+{


Move the function to somewhere above, like above the "/* Entrypoints */" 
section (and maybe introduce another section)? The various parts are 
more-or-less arranged in a particular order, so it's like going back to 
implementing concrete things after finishing everything and calling it a 
day.


Also you forgot to remove the now inappropriate comment about this 
helper in tcg-target.h.



+tcg_insn_unit i1, i2;
+
+ptrdiff_t offset = addr - jmp_rx;
+
+if (offset == sextreg(offset, 0, 28)) {
+i1 = OPC_B | ((offset >> 18) & 0x3ff) | ((offset << 8) & 0x3fffc00);
Use encode_sd10k16_insn instead. No need to juggle the bits yourself and 
you get nice range assertion for free.

+i2 = NOP;
+} else {
+offset >>= 2;
+
+ptrdiff_t upper, lower;
Promote the declaration to the top of the block (before offset 
shifting), IIRC that's the official coding style.

+upper = ((offset 

Re: [PATCH 1/2] tcg/loongarch64: Implement INDEX_op_neg_i{32,64}

2022-10-12 Thread WANG Xuerui

Hi,

On 2022/10/12 17:13, Qi Hu wrote:

Signed-off-by: Qi Hu 
---
  tcg/loongarch64/tcg-target.c.inc | 9 +
  tcg/loongarch64/tcg-target.h | 4 ++--
  2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index a3debf6da7..f5a214a17f 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1125,6 +1125,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
  tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO);
  break;
  
+case INDEX_op_neg_i32:

+tcg_out_opc_sub_w(s, a0, TCG_REG_ZERO, a1);
+break;
+case INDEX_op_neg_i64:
+tcg_out_opc_sub_d(s, a0, TCG_REG_ZERO, a1);
+break;
+
  case INDEX_op_nor_i32:
  case INDEX_op_nor_i64:
  if (c2) {
@@ -1503,6 +1510,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
  case INDEX_op_ext_i32_i64:
  case INDEX_op_not_i32:
  case INDEX_op_not_i64:
+case INDEX_op_neg_i32:
+case INDEX_op_neg_i64:
  case INDEX_op_extract_i32:
  case INDEX_op_extract_i64:
  case INDEX_op_bswap16_i32:
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index d58a6162f2..67380b2432 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -114,7 +114,7 @@ typedef enum {
  #define TCG_TARGET_HAS_bswap16_i32  1
  #define TCG_TARGET_HAS_bswap32_i32  1
  #define TCG_TARGET_HAS_not_i32  1
-#define TCG_TARGET_HAS_neg_i32  0
+#define TCG_TARGET_HAS_neg_i32  1
  #define TCG_TARGET_HAS_andc_i32 1
  #define TCG_TARGET_HAS_orc_i32  1
  #define TCG_TARGET_HAS_eqv_i32  0
@@ -150,7 +150,7 @@ typedef enum {
  #define TCG_TARGET_HAS_bswap32_i64  1
  #define TCG_TARGET_HAS_bswap64_i64  1
  #define TCG_TARGET_HAS_not_i64  1
-#define TCG_TARGET_HAS_neg_i64  0
+#define TCG_TARGET_HAS_neg_i64  1
  #define TCG_TARGET_HAS_andc_i64 1
  #define TCG_TARGET_HAS_orc_i64  1
  #define TCG_TARGET_HAS_eqv_i64  0
The whole change is not necessary, if target doesn't have neg then the 
target-independent logic already makes sure a sub with the same 
semantics is emitted. This is explained in the commit message of that 
commit introducing add/sub support.




[PATCH] linux-user: Implement faccessat2

2022-10-09 Thread WANG Xuerui
User space has been preferring this syscall for a while, due to its
closer match with C semantics, and newer platforms such as LoongArch
apparently have libc implementations that don't fallback to faccessat
so normal access checks are failing without the emulation in place.

Tested by successfully emerging several packages within a Gentoo loong
stage3 chroot, emulated on amd64 with help of static qemu-loongarch64.

Reported-by: Andreas K. Hüttel 
Signed-off-by: WANG Xuerui 
---
 linux-user/strace.list | 3 +++
 linux-user/syscall.c   | 9 +
 2 files changed, 12 insertions(+)

diff --git a/linux-user/strace.list b/linux-user/strace.list
index a87415bf3d..3df2184580 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -178,6 +178,9 @@
 #ifdef TARGET_NR_faccessat
 { TARGET_NR_faccessat, "faccessat" , NULL, print_faccessat, NULL },
 #endif
+#ifdef TARGET_NR_faccessat2
+{ TARGET_NR_faccessat2, "faccessat2" , NULL, print_faccessat, NULL },
+#endif
 #ifdef TARGET_NR_fadvise64
 { TARGET_NR_fadvise64, "fadvise64" , NULL, NULL, NULL },
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2e954d8dbd..a81f0b65b9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9110,6 +9110,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 unlock_user(p, arg2, 0);
 return ret;
 #endif
+#if defined(TARGET_NR_faccessat2) && defined(__NR_faccessat2)
+case TARGET_NR_faccessat2:
+if (!(p = lock_user_string(arg2))) {
+return -TARGET_EFAULT;
+}
+ret = get_errno(faccessat(arg1, p, arg3, arg4));
+unlock_user(p, arg2, 0);
+return ret;
+#endif
 #ifdef TARGET_NR_nice /* not on alpha */
 case TARGET_NR_nice:
 return get_errno(nice(arg1));
-- 
2.38.0




[PATCH] linux-user: Fix struct statfs ABI on loongarch64

2022-10-06 Thread WANG Xuerui
Previously the 32-bit version was incorrectly chosen, leading to funny
but incorrect output from e.g. df(1). Simply select the version
corresponding to the 64-bit asm-generic definition.

For reference, this program should produce the same output no matter
natively compiled or not, for loongarch64 or not:

```c
#include 
#include 

int main(int argc, const char *argv[])
{
  struct statfs b;
  if (statfs(argv[0], ))
return 1;

  printf("f_type = 0x%lx\n", b.f_type);
  printf("f_bsize = %ld\n", b.f_bsize);
  printf("f_blocks = %ld\n", b.f_blocks);
  printf("f_bfree = %ld\n", b.f_bfree);
  printf("f_bavail = %ld\n", b.f_bavail);

  return 0;
}

// Native and expected emulated output after the fix:
//
// f_type = 0x9123683e
// f_bsize = 4096
// f_blocks = 268435456
// f_bfree = 168406890
// f_bavail = 168355058

// Output before the fix, note the messed layout:
//
// f_type = 0x10009123683e
// f_bsize = 723302085239504896
// f_blocks = 168355058
// f_bfree = 2250817541779750912
// f_bavail = 1099229433104
```

Fixes: 1f63019632 ("linux-user: Add LoongArch syscall support")
Signed-off-by: WANG Xuerui 
Cc: Song Gao 
Cc: Xiaojuan Yang 
Cc: Andreas K. Hüttel 
---
 linux-user/syscall_defs.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 01ee10a88f..77864de57f 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2262,7 +2262,8 @@ struct target_statfs64 {
 };
 #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \
defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \
-   defined(TARGET_RISCV)) && !defined(TARGET_ABI32)
+   defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64)) && \
+   !defined(TARGET_ABI32)
 struct target_statfs {
abi_long f_type;
abi_long f_bsize;
-- 
2.38.0




[PATCH RESEND] linux-user: Fix struct statfs ABI on loongarch64

2022-10-06 Thread WANG Xuerui
Previously the 32-bit version was incorrectly chosen, leading to funny
but incorrect output from e.g. df(1). Simply select the version
corresponding to the 64-bit asm-generic definition.

For reference, this program should produce the same output no matter
natively compiled or not, for loongarch64 or not:

```c
#include 
#include 

int main(int argc, const char *argv[])
{
  struct statfs b;
  if (statfs(argv[0], ))
return 1;

  printf("f_type = 0x%lx\n", b.f_type);
  printf("f_bsize = %ld\n", b.f_bsize);
  printf("f_blocks = %ld\n", b.f_blocks);
  printf("f_bfree = %ld\n", b.f_bfree);
  printf("f_bavail = %ld\n", b.f_bavail);

  return 0;
}

// Example output on my amd64 box, with the test binary residing on a
// btrfs partition.

// Native and emulated output after the fix:
//
// f_type = 0x9123683e
// f_bsize = 4096
// f_blocks = 268435456
// f_bfree = 168406890
// f_bavail = 168355058

// Output before the fix, note the messed layout:
//
// f_type = 0x10009123683e
// f_bsize = 723302085239504896
// f_blocks = 168355058
// f_bfree = 2250817541779750912
// f_bavail = 1099229433104
```

Fixes: 1f63019632 ("linux-user: Add LoongArch syscall support")
Signed-off-by: WANG Xuerui 
Cc: Song Gao 
Cc: Xiaojuan Yang 
Cc: Andreas K. Hüttel 
---

Resend with amended commit message to 100% clarify the example output
are generated on my box and will differ for everyone else. Sorry for
the noise.

 linux-user/syscall_defs.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 01ee10a88f..77864de57f 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2262,7 +2262,8 @@ struct target_statfs64 {
 };
 #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \
defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \
-   defined(TARGET_RISCV)) && !defined(TARGET_ABI32)
+   defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64)) && \
+   !defined(TARGET_ABI32)
 struct target_statfs {
abi_long f_type;
abi_long f_bsize;
-- 
2.38.0




[PATCH] linux-user: Fix more MIPS n32 syscall ABI issues

2022-10-06 Thread WANG Xuerui
In commit 80f0fe3a85 ("linux-user: Fix syscall parameter handling for
MIPS n32") the ABI problem regarding offset64 on MIPS n32 was fixed,
but still some cases remain where the n32 is incorrectly treated as any
other 32-bit ABI that passes 64-bit arguments in pairs of GPRs. Fix by
excluding TARGET_ABI_MIPSN32 from various TARGET_ABI_BITS == 32 checks.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/1238
Signed-off-by: WANG Xuerui 
Cc: Philippe Mathieu-Daudé 
Cc: Jiaxun Yang 
Cc: Andreas K. Hüttel 
Cc: Joshua Kinard 
---

Note: I can't reproduce the crash with neither MIPS n32 sysroot at my hand
(a self-built one for Loongson-2F, and 
stage3-mips64_n32-openrc-20221001T170527Z),
so I can only verify by looking at the (host and qemu) strace outputs, and
would have to ask you to review/test this harder. Thanks.

 linux-user/syscall.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2e954d8dbd..8b2d39fe73 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11793,7 +11793,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 return -host_to_target_errno(ret);
 #endif
 
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
 
 #ifdef TARGET_NR_fadvise64_64
 case TARGET_NR_fadvise64_64:
@@ -11920,7 +11920,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 return get_errno(sys_gettid());
 #ifdef TARGET_NR_readahead
 case TARGET_NR_readahead:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
 if (regpairs_aligned(cpu_env, num)) {
 arg2 = arg3;
 arg3 = arg4;
@@ -12612,7 +12612,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 #endif /* CONFIG_EVENTFD  */
 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
 case TARGET_NR_fallocate:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
   target_offset64(arg5, arg6)));
 #else
@@ -12623,7 +12623,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 #if defined(CONFIG_SYNC_FILE_RANGE)
 #if defined(TARGET_NR_sync_file_range)
 case TARGET_NR_sync_file_range:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
 #if defined(TARGET_MIPS)
 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
 target_offset64(arg5, arg6), arg7));
@@ -12645,7 +12645,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 case TARGET_NR_arm_sync_file_range:
 #endif
 /* This is like sync_file_range but the arguments are reordered */
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
 target_offset64(arg5, arg6), arg2));
 #else
-- 
2.38.0




Re: [PATCH v1 4/7] contrib/gitdm: add WANG Xuerui to individual contributers

2022-09-26 Thread WANG Xuerui

Hi,

On 2022/9/26 21:46, Alex Bennée wrote:

His blog confirms he is not affiliated with Longsoon.

It's spelled "Loongson" ;-)


Signed-off-by: Alex Bennée 
Cc: WANG Xuerui 
---
  contrib/gitdm/group-map-individuals | 1 +
  1 file changed, 1 insertion(+)

diff --git a/contrib/gitdm/group-map-individuals 
b/contrib/gitdm/group-map-individuals
index 0ec003048c..6a3b593df0 100644
--- a/contrib/gitdm/group-map-individuals
+++ b/contrib/gitdm/group-map-individuals
@@ -36,3 +36,4 @@ chetan4wind...@gmail.com
  akihiko.od...@gmail.com
  si...@simonsafar.com
  p...@nowt.org
+g...@xen0n.name


And thanks for updating it for me!

So with the typo fix:

Reviewed-by: WANG Xuerui 



Re: [PATCH for-7.1 3/4] target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"

2022-08-17 Thread WANG Xuerui

On 2022/8/17 21:26, Richard Henderson wrote:

On 8/17/22 04:10, WANG Xuerui wrote:
 From my own experiences, different use cases care about different 
aspects of the CPU, and that IMO is an argument in favor of providing 
both (high-fidelity models named after actual product model names, 
and virtual models named after ISA levels). But before we have truly 
high-fidelity models I think we should start with the virtual ones 
first. And don't pretend the currently implemented model is LA464 -- 
the kernel change I've linked to [1] implies the opposite.


No, it simply pointed to a bug in qemu that could have been fixed.

The trouble with inventing virtual models is that no one knows what 
they mean.  Targeting real hardware is better, because we have a 
documented standard.


Hmm, I've looked up more context and it is indeed reasonable to 
generally name the QEMU models after real existing models. But in this 
case we could face a problem with Loongson's nomenclature: all of 
Loongson 3A5000, 3C5000 and 3C5000L are LA464, yet they should be 
distinguishable software-side by checking the model name CSR. But with 
only one CPU model that is LA464, currently this CSR is hard-coded to 
read "3A5000", and this can hurt IMO. And when we finally add LA264 and 
LA364 they would be identical ISA-level-wise, again the only 
differentiator is the model name CSR.


And by "not high-fidelity", I mean some of the features present on real 
HW might never get implemented, or actually implementable, like the DVFS 
mechanism needed by cpufreq. And I believe Bibo wouldn't have to change 
the kernel if it's not needed after all to run the unmodified upstream 
kernel on top of qemu-system-loongarch64. (I would of course accept, and 
learn something along the way, if this turns out not to be the case though.)


Lastly, the "ISA level" I proposed is not arbitrarily made up; it's 
direct reference to the ISA manual revision. Each time the ISA gets some 
addition/revision the ISA manual has to be updated, and currently the 
manual's revision is the only reliable source of said information. 
(Loongson has a history of naming cores badly, like with the MIPS 3B1500 
and 3A4000, both were "GS464V"; and 3A5000 was originally GS464V too, 
even though the insn encodings and some semantics have been entirely 
different.)


In conclusion, I'd accept the micro-architecture naming if the model CSR 
behavior could be sorted out, otherwise I'd personally prefer real model 
names if ISA level naming is not going to fly. This is not a strong 
objection to the current way of doing things though, more like some 
minor but anyway needed discussion that happened a bit late. Sorry for 
not chiming in earlier during the review process.




Re: [PATCH for-7.1 3/4] target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"

2022-08-17 Thread WANG Xuerui

On 2022/8/17 16:11, gaosong wrote:


在 2022/8/17 上午10:36, chen huacai 写道:

Hi, Richard and Xuerui,

On Mon, Aug 15, 2022 at 4:54 AM Richard Henderson
 wrote:

On 8/14/22 09:55, WANG Xuerui wrote:

From: WANG Xuerui 

The only LoongArch CPU implemented is modeled after the Loongson 
3A5000,

but it is not the real thing, ...
The 3A5000 is the SoC, as far as I could find, and the documentation 
of that says the core

is named the la464.


In general, high-fidelity models can and should be named after the 
real
hardware model, while generic emulation-oriented models should be 
named

after ISA levels.
This wasn't intended to be a generic emulation model, as far as I 
know.  There are missing

features, but presumably those would eventually be filled in.



For now, the best reference for LoongArch ISA levels
is the revision number of the LoongArch ISA Manual, of which v1.00 is
still the latest. (v1.01 and v1.02 are minor revisions without
substantive change.)

As defined by various specs, the vendor and model names are also
reflected in respective CSRs, and are 8 bytes long. So, rename "la464"
to "qemu64-v1.00", with "QEMU64" as vendor name and "v1.00" as model
name.
Eh, I suppose.  I'm not really keen on this though, as I would 
presume there will be
eventual forward progress on completing the real cpu model. We 
simply won't give any

compatibility guarantees for loongarch until we are ready to do so.

In my opinion, real cpu name (Loongson-3A5000, Loongson-3A6000, etc.)
and generic qemu emulated name (qemu64-v1.00, qemu64-v2.00, vx.xx is
the ISA level, I found this style is used for x86) are both
acceptable. But la464 is not a good cpu name, because la264 and la464
are in the same ISA level, while la664 will be in a new level.
I think that 'la264' , 'la464' and 'la664'  are  cpu core name. used 
them as cpu type is more suitable.
Although la264 and la464 are in the same ISA level,   but the features 
should be different.


From my own experiences, different use cases care about different 
aspects of the CPU, and that IMO is an argument in favor of providing 
both (high-fidelity models named after actual product model names, and 
virtual models named after ISA levels). But before we have truly 
high-fidelity models I think we should start with the virtual ones 
first. And don't pretend the currently implemented model is LA464 -- the 
kernel change I've linked to [1] implies the opposite.


If you're emulating certain boards to test kernels/drivers or similar 
things, it could help to be able to specify exact CPU models and/or 
machine type. However, for the linux-user case, it is almost always the 
ISA level that actually matters, and I don't think LA264/LA364/LA464 are 
going to differ w.r.t. unprivileged instruction behavior. Having to 
choose an overly specific model for a broad ISA level match seems 
inappropriate to my aesthetic sense.


[1]: 
https://github.com/torvalds/linux/commit/71610ab1d017e131a9888ef8acd035284fb0e1dd




[PATCH for-7.1 0/4] Last-minute LoongArch CPU model naming tweaks

2022-08-14 Thread WANG Xuerui
Hi,

Some people are already testing out the 7.1 RCs for the LoongArch
emulation, and have suggested improvements to the CPU model naming
scheme. While assessing the situation I also found the documentation
already out-of-date, in addition to being especially hard to read (for a
Chinese who could *not* understand Chinglish, though).

Sorry for being really late (I've mostly been focusing on my day job and
LLVM bringup work for LoongArch recently), but hopefully these changes
could still be integrated, because target/loongarch is fresh addition
for 7.1 nobody should have depended on its implementation details yet.
Anyway, since the "new world" ecosystem isn't expected to mature and
attract lots of users very soon, it could be acceptable to just punt
this to 7.2, and issue incompatible change notices as usual. I
personally would be fine with either.

WANG Xuerui (4):
  target/loongarch: Only allow short -cpu arguments without type name
suffix
  target/loongarch: Trim type name suffix in -cpu help output
  target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"
  docs, target/loongarch: Rewrite the LoongArch docs

 docs/system/loongarch/loongson3.rst | 41 
 docs/system/loongarch/virt.rst  | 41 
 hw/loongarch/virt.c | 14 +---
 target/loongarch/README | 99 -
 target/loongarch/README.md  | 75 ++
 target/loongarch/cpu.c  | 21 +++---
 6 files changed, 128 insertions(+), 163 deletions(-)
 delete mode 100644 docs/system/loongarch/loongson3.rst
 create mode 100644 docs/system/loongarch/virt.rst
 delete mode 100644 target/loongarch/README
 create mode 100644 target/loongarch/README.md

-- 
2.35.1




[PATCH for-7.1 2/4] target/loongarch: Trim type name suffix in -cpu help output

2022-08-14 Thread WANG Xuerui
From: WANG Xuerui 

Also add a header and indentation for each entry, while at it.

Signed-off-by: WANG Xuerui 
---
 target/loongarch/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index dc233ee209..4663539443 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -416,13 +416,15 @@ static void loongarch_la464_initfn(Object *obj)
 static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
 {
 const char *typename = object_class_get_name(OBJECT_CLASS(data));
+int len = strlen(typename) - strlen(LOONGARCH_CPU_TYPE_SUFFIX);
 
-qemu_printf("%s\n", typename);
+qemu_printf("  %.*s\n", len, typename);
 }
 
 void loongarch_cpu_list(void)
 {
 GSList *list;
+qemu_printf("Available CPUs:\n");
 list = object_class_get_list_sorted(TYPE_LOONGARCH_CPU, false);
 g_slist_foreach(list, loongarch_cpu_list_entry, NULL);
 g_slist_free(list);
-- 
2.35.1




[PATCH for-7.1 4/4] docs, target/loongarch: Rewrite the LoongArch docs

2022-08-14 Thread WANG Xuerui
From: WANG Xuerui 

Much information is already outdated in its current form, not to mention
the hard-to-understand Chinglish. Rewrite to hopefully de-duplicate and
re-organize things, and reflect the latest status of LoongArch at
upstream.

Signed-off-by: WANG Xuerui 
---
 docs/system/loongarch/loongson3.rst | 41 
 docs/system/loongarch/virt.rst  | 41 
 target/loongarch/README | 99 -
 target/loongarch/README.md  | 75 ++
 4 files changed, 116 insertions(+), 140 deletions(-)
 delete mode 100644 docs/system/loongarch/loongson3.rst
 create mode 100644 docs/system/loongarch/virt.rst
 delete mode 100644 target/loongarch/README
 create mode 100644 target/loongarch/README.md

diff --git a/docs/system/loongarch/loongson3.rst 
b/docs/system/loongarch/loongson3.rst
deleted file mode 100644
index fa3acd01c0..00
--- a/docs/system/loongarch/loongson3.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-:orphan:
-
-==
-loongson3 virt generic platform (``virt``)
-==
-
-The ``virt`` machine use gpex host bridge, and there are some
-emulated devices on virt board, such as loongson7a RTC device,
-IOAPIC device, ACPI device and so on.
-
-Supported devices
--
-
-The ``virt`` machine supports:
-- Gpex host bridge
-- Ls7a RTC device
-- Ls7a IOAPIC device
-- Ls7a ACPI device
-- Fw_cfg device
-- PCI/PCIe devices
-- Memory device
-- CPU device. Type: Loongson-3A5000.
-
-CPU and machine Type
-
-
-The ``qemu-system-loongarch64`` provides emulation for virt
-machine. You can specify the machine type ``virt`` and
-cpu type ``Loongson-3A5000``.
-
-Boot options
-
-
-Now the ``virt`` machine can run test program in ELF format and the
-method of compiling is in target/loongarch/README.
-
-.. code-block:: bash
-
-  $ qemu-system-loongarch64 -machine virt -m 4G -cpu Loongson-3A5000 \
-  -smp 1 -kernel hello -monitor none -display none \
-  -chardev file,path=hello.out,id=output -serial chardev:output
diff --git a/docs/system/loongarch/virt.rst b/docs/system/loongarch/virt.rst
new file mode 100644
index 00..2d8f7e1db5
--- /dev/null
+++ b/docs/system/loongarch/virt.rst
@@ -0,0 +1,41 @@
+:orphan:
+
+=
+LoongArch generic virtualized platform (``virt``)
+=
+
+The ``virt`` machine has a GPEX host bridge, and some more emulated devices
+such as the LS7A RTC, IOAPIC, ACPI device and so on.
+
+Being a machine type designed for virtualized use cases, the machine resembles
+a Loongson 3A5000 + LS7A1000 board, but is not an exact emulation.
+For example, only cascading of the EXTIOI interrupt is implemented.
+Also, only the RTC block of the LS7A1000 is emulated; for the other devices
+the QEMU models are used.
+Normally you do not need to care about any of these.
+
+Supported devices
+-
+
+The ``virt`` machine supports:
+
+- GPEX host bridge
+- LS7A RTC device
+- LS7A IOAPIC device
+- LS7A ACPI device
+- fw_cfg device
+- PCI/PCIe devices
+- Memory device
+- CPU device. Defaults to ``qemu64-v1.00``.
+
+Boot options
+
+
+Some more information could be found in the QEMU sources at
+``target/loongarch/README.md``. A simple example being:
+
+.. code-block:: bash
+
+  $ qemu-system-loongarch64 -machine virt -m 4G -smp 1 -kernel hello \
+  -monitor none -display none \
+  -chardev file,path=hello.out,id=output -serial chardev:output
diff --git a/target/loongarch/README b/target/loongarch/README
deleted file mode 100644
index 1823375d04..00
--- a/target/loongarch/README
+++ /dev/null
@@ -1,99 +0,0 @@
-- Introduction
-
-  LoongArch is the general processor architecture of Loongson.
-
-  The following versions of the LoongArch core are supported
-core: 3A5000
-
https://github.com/loongson/LoongArch-Documentation/releases/download/2021.08.17/LoongArch-Vol1-v1.00-EN.pdf
-
-  We can get the latest loongarch documents at 
https://github.com/loongson/LoongArch-Documentation/tags.
-
-
-- System emulation
-
-  Mainly emulate a virt 3A5000 board and ls7a bridge that is not exactly the 
same as the host.
-  3A5000 support multiple interrupt cascading while here we just emulate the 
extioi interrupt
-  cascading. LS7A1000 host bridge support multiple devices, such as sata, 
gmac, uart, rtc
-  and so on. But we just realize the rtc. Others use the qemu common devices. 
It does not affect
-  the general use. We also introduced the emulation of devices at 
docs/system/loongarch/virt.rst.
-
-  This version only supports running binary files in ELF format, and does not 
depend on BIOS and kernel file.
-  You can compile the test program with 'make & make check-tcg' and run the 
test case with the following command:
-
-  1. Install LoongArch cross-tools on X86 machines.
-
-Download cross-t

[PATCH for-7.1 3/4] target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"

2022-08-14 Thread WANG Xuerui
From: WANG Xuerui 

The only LoongArch CPU implemented is modeled after the Loongson 3A5000,
but it is not the real thing, and at least one feature [1] is missing
that actually made the model incompatible with the real 3A5000. What's
more, the model is currently named "la464", while none of the
micro-architecture-specific things are currently present, further making
things needlessly complex.

In general, high-fidelity models can and should be named after the real
hardware model, while generic emulation-oriented models should be named
after ISA levels. For now, the best reference for LoongArch ISA levels
is the revision number of the LoongArch ISA Manual, of which v1.00 is
still the latest. (v1.01 and v1.02 are minor revisions without
substantive change.)

As defined by various specs, the vendor and model names are also
reflected in respective CSRs, and are 8 bytes long. So, rename "la464"
to "qemu64-v1.00", with "QEMU64" as vendor name and "v1.00" as model
name.

As the QEMU 7.1 hasn't been officially released, no downstream is
expected to depend on the old name, so this change should be safe for
7.1.

[1]: 
https://lore.kernel.org/loongarch/20220726094049.7200-2-maob...@loongson.cn/

Signed-off-by: WANG Xuerui 
---
 hw/loongarch/virt.c| 14 ++
 target/loongarch/cpu.c |  6 +++---
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 5cc0b05538..35e2174a17 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -626,7 +626,6 @@ static void 
loongarch_direct_kernel_boot(LoongArchMachineState *lams)
 static void loongarch_init(MachineState *machine)
 {
 LoongArchCPU *lacpu;
-const char *cpu_model = machine->cpu_type;
 ram_addr_t offset = 0;
 ram_addr_t ram_size = machine->ram_size;
 uint64_t highram_size = 0;
@@ -634,15 +633,6 @@ static void loongarch_init(MachineState *machine)
 LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
 int i;
 
-if (!cpu_model) {
-cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
-}
-
-if (!strstr(cpu_model, "la464")) {
-error_report("LoongArch/TCG needs cpu type la464");
-exit(1);
-}
-
 if (ram_size < 1 * GiB) {
 error_report("ram_size must be greater than 1G.");
 exit(1);
@@ -749,10 +739,10 @@ static void loongarch_class_init(ObjectClass *oc, void 
*data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 
-mc->desc = "Loongson-3A5000 LS7A1000 machine";
+mc->desc = "LoongArch64 v1.00-compatible LS7A1000 machine";
 mc->init = loongarch_init;
 mc->default_ram_size = 1 * GiB;
-mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
+mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("qemu64-v1.00");
 mc->default_ram_id = "loongarch.ram";
 mc->max_cpus = LOONGARCH_MAX_VCPUS;
 mc->is_default = 1;
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 4663539443..0a41509a0c 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -527,9 +527,9 @@ static uint64_t loongarch_qemu_read(void *opaque, hwaddr 
addr, unsigned size)
 return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
1ULL << IOCSRF_CSRIPI;
 case VENDOR_REG:
-return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
+return 0x3436554d4551ULL; /* "QEMU64" */
 case CPUNAME_REG:
-return 0x303030354133ULL; /* "3A5000" */
+return 0x30302e3176ULL;   /* "v1.00" */
 case MISC_FUNC_REG:
 return 1ULL << IOCSRM_EXTIOI_EN;
 }
@@ -715,7 +715,7 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 .class_size = sizeof(LoongArchCPUClass),
 .class_init = loongarch_cpu_class_init,
 },
-DEFINE_LOONGARCH_CPU_TYPE("la464", loongarch_la464_initfn),
+DEFINE_LOONGARCH_CPU_TYPE("qemu64-v1.00", loongarch_la464_initfn),
 };
 
 DEFINE_TYPES(loongarch_cpu_type_infos)
-- 
2.35.1




[PATCH for-7.1 1/4] target/loongarch: Only allow short -cpu arguments without type name suffix

2022-08-14 Thread WANG Xuerui
From: WANG Xuerui 

Previously both "foo" and "foo-loongarch-cpu" are accepted for the -cpu
command-line option, the latter of which being excessively long and
redundant, hence unwanted. Remove support for consistency with other
targets and simpler code.

Signed-off-by: WANG Xuerui 
---
 target/loongarch/cpu.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 941e2772bc..dc233ee209 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -573,14 +573,11 @@ static ObjectClass *loongarch_cpu_class_by_name(const 
char *cpu_model)
 {
 ObjectClass *oc;
 
-oc = object_class_by_name(cpu_model);
+g_autofree char *typename = g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"),
+cpu_model);
+oc = object_class_by_name(typename);
 if (!oc) {
-g_autofree char *typename 
-= g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
-oc = object_class_by_name(typename);
-if (!oc) {
-return NULL;
-}
+return NULL;
 }
 
 if (object_class_dynamic_cast(oc, TYPE_LOONGARCH_CPU)
-- 
2.35.1




Re: [PATCH v15 6/9] default-configs: Add loongarch linux-user support

2022-06-09 Thread WANG Xuerui

On 2022/6/9 10:42, Song Gao wrote:

This patch adds loongarch64 linux-user default configs file.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
  configs/targets/loongarch64-linux-user.mak | 3 +++
  1 file changed, 3 insertions(+)
  create mode 100644 configs/targets/loongarch64-linux-user.mak

diff --git a/configs/targets/loongarch64-linux-user.mak 
b/configs/targets/loongarch64-linux-user.mak
new file mode 100644
index 00..7d1b964020
--- /dev/null
+++ b/configs/targets/loongarch64-linux-user.mak
@@ -0,0 +1,3 @@
+# Default configuration for loongarch64-linux-user
+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch


Simple enough.

Reviewed-by: WANG Xuerui 




Re: [PATCH v15 8/9] target/loongarch: Adjust functions and structure to support user-mode

2022-06-09 Thread WANG Xuerui
, int 
size,
  bool probe, uintptr_t retaddr);
  
  hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);

+#endif
  
  int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);

  int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index d87049851f..49fbd1343c 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -49,14 +49,24 @@ target_ulong helper_bitswap(target_ulong v)
  void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk)
  {
  if (rj > rk) {
+#ifdef CONFIG_USER_ONLY
+cpu_loop_exit_sigsegv(env_cpu(env), GETPC(),
+  MMU_DATA_LOAD, true, GETPC());
+#else
  do_raise_exception(env, EXCCODE_ADEM, GETPC());
+#endif
  }
  }
  
  void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk)

  {
  if (rj <= rk) {
+#ifdef CONFIG_USER_ONLY
+cpu_loop_exit_sigsegv(env_cpu(env), GETPC(),
+  MMU_DATA_LOAD, true, GETPC());
+#else
  do_raise_exception(env, EXCCODE_ADEM, GETPC());
+#endif
  }
  }
  
@@ -84,6 +94,7 @@ target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj)

  return rj > 21 ? 0 : env->cpucfg[rj];
  }
  
+#ifndef CONFIG_USER_ONLY

  uint64_t helper_rdtime_d(CPULoongArchState *env)
  {
  uint64_t plv;
@@ -131,3 +142,4 @@ void helper_idle(CPULoongArchState *env)
  cs->halted = 1;
  do_raise_exception(env, EXCP_HLT, 0);
  }
+#endif


The other parts seem to be good.

With the rdtime[lh].w bug fixed:

Reviewed-by: WANG Xuerui 




Re: [PATCH v15 4/9] linux-user: Add LoongArch syscall support

2022-06-09 Thread WANG Xuerui

On 2022/6/9 10:42, Song Gao wrote:

We should disable '__BITS_PER_LONG' at [1] before run gensyscalls.sh

  [1] arch/loongarch/include/uapi/asm/bitsperlong.h


I'm not sure why this is necessary, is this for building on 32-bit where 
__BITS_PER_LONG are (incorrectly) reflecting the host bitness?


If this is the case, arch/riscv uses the same trick (they are defining 
__BITS_PER_LONG as (__SIZEOF_POINTER__ * 8), which is essentially the 
same), so they should fail without the hack described here as well. I 
don't know if something else could be tweaked to get rid of this hack 
(currently unable to investigate deeper for you, taking a break 
reviewing this in the middle of my day job).




Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
  linux-user/loongarch64/syscall_nr.h | 312 
  linux-user/loongarch64/target_syscall.h |  48 
  linux-user/syscall_defs.h   |  12 +-
  scripts/gensyscalls.sh  |   1 +
  4 files changed, 368 insertions(+), 5 deletions(-)
  create mode 100644 linux-user/loongarch64/syscall_nr.h
  create mode 100644 linux-user/loongarch64/target_syscall.h

[snip]

diff --git a/linux-user/loongarch64/target_syscall.h 
b/linux-user/loongarch64/target_syscall.h
new file mode 100644
index 00..8b5de52124
--- /dev/null
+++ b/linux-user/loongarch64/target_syscall.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_SYSCALL_H
+#define LOONGARCH_TARGET_SYSCALL_H
+
+#include "qemu/units.h"
+
+/*
+ * this struct defines the way the registers are stored on the
+ * stack during a system call.
+ */
+
+struct target_pt_regs {
+/* Saved main processor registers. */
+target_ulong regs[32];
+
+/* Saved special registers. */
+struct {
+target_ulong era;
+target_ulong badv;
+target_ulong crmd;
+target_ulong prmd;
+target_ulong euen;
+target_ulong ecfg;
+target_ulong estat;
+} csr;
+target_ulong orig_a0;
+target_ulong __last[0];
+};
+
+#define UNAME_MACHINE "loongarch64"
+#define UNAME_MINIMUM_RELEASE "5.19.0"
+
+#define TARGET_MCL_CURRENT 1
+#define TARGET_MCL_FUTURE  2
+#define TARGET_MCL_ONFAULT 4
+
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPULoongArchState *env)
+{
+return 64 * KiB;
+}
+
+#endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 4587b62ac9..b5b9a02816 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -74,7 +74,7 @@
  || defined(TARGET_M68K) || defined(TARGET_CRIS) \
  || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
  || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \
-|| defined(TARGET_XTENSA)
+|| defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64)
  
  #define TARGET_IOC_SIZEBITS	14

  #define TARGET_IOC_DIRBITS2
@@ -2084,8 +2084,9 @@ struct target_stat64  {
  abi_ulong __unused5;
  };
  
-#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) \

-|| defined(TARGET_RISCV) || defined(TARGET_HEXAGON)
+#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || \
+  defined(TARGET_RISCV) || defined(TARGET_HEXAGON) || \
+  defined(TARGET_LOONGARCH64)
  
  /* These are the asm-generic versions of the stat and stat64 structures */
The finalized LoongArch system call interface doesn't include stat, 
fstat or newfstatat. So do we still have to pull in the definitions for 
stat structures?
  
@@ -2113,7 +2114,7 @@ struct target_stat {

  unsigned int __unused5;
  };
  
-#if !defined(TARGET_RISCV64)

+#if !defined(TARGET_RISCV64) && !defined(TARGET_LOONGARCH64)
  #define TARGET_HAS_STRUCT_STAT64
  struct target_stat64 {
  uint64_t st_dev;

Similarly here.

@@ -2258,7 +2259,8 @@ struct target_statfs64 {
  };
  #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \
 defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \
-   defined(TARGET_RISCV)) && !defined(TARGET_ABI32)
+   defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64)) && \
+   !defined(TARGET_ABI32)
  struct target_statfs {
abi_long f_type;
abi_long f_bsize;
diff --git a/scripts/gensyscalls.sh b/scripts/gensyscalls.sh
index 8fb450e3c9..b69e1938ab 100755
--- a/scripts/gensyscalls.sh
+++ b/scripts/gensyscalls.sh
@@ -99,4 +99,5 @@ generate_syscall_nr openrisc 32 
"$output/linux-user/openrisc/syscall_nr.h"
  generate_syscall_nr riscv 32 "$output/linux-user/riscv/syscall32_nr.h"
  generate_syscall_nr riscv 64 "$output/linux-user/riscv/syscall64_nr.h"
  generate_syscall_nr hexagon 32 "$output/linux-user/hexagon/syscall_nr.h"
+generate_syscall_nr loongarch 64 "$output/linux-user/loongarch64/syscall_nr.h"
  rm -fr "$TMP"




Re: [PATCH v15 1/9] linux-user: Add LoongArch generic header files

2022-06-09 Thread WANG Xuerui



On 2022/6/9 10:42, Song Gao wrote:

This includes:
- sockbits.h
- target_errno_defs.h
- target_fcntl.h
- termbits.h
- target_resource.h
- target_structs.h

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
  linux-user/loongarch64/sockbits.h  | 11 +++
  linux-user/loongarch64/target_errno_defs.h | 12 
  linux-user/loongarch64/target_fcntl.h  | 11 +++
  linux-user/loongarch64/target_prctl.h  |  1 +
  linux-user/loongarch64/target_resource.h   | 11 +++
  linux-user/loongarch64/target_structs.h| 11 +++
  linux-user/loongarch64/termbits.h  | 11 +++
  7 files changed, 68 insertions(+)
  create mode 100644 linux-user/loongarch64/sockbits.h
  create mode 100644 linux-user/loongarch64/target_errno_defs.h
  create mode 100644 linux-user/loongarch64/target_fcntl.h
  create mode 100644 linux-user/loongarch64/target_prctl.h
  create mode 100644 linux-user/loongarch64/target_resource.h
  create mode 100644 linux-user/loongarch64/target_structs.h
  create mode 100644 linux-user/loongarch64/termbits.h


So this is all nicely generic.

Reviewed-by: WANG Xuerui 




Re: [PATCH for-7.0 v5] qemu-binfmt-conf.sh: mips: allow nonzero EI_ABIVERSION, distinguish o32 and n32

2022-03-28 Thread WANG Xuerui

On 3/29/22 07:39, Philippe Mathieu-Daudé wrote:

On 28/3/22 22:49, Andreas K. Hüttel wrote:

With the command line flag -mplt and a recent toolchain, ELF binaries
generated by gcc can obtain EI_ABIVERSION=1, which makes, e.g., gcc
three-stage bootstrap in a mips-unknown-linux-gnu qemu-user chroot
fail since the binfmt-misc magic does not match anymore. Also other
values are technically possible. qemu executes these binaries just
fine, so relax the mask for the EI_ABIVERSION byte at offset 0x08.

In addition, extend magic string to distinguish mips o32 and n32 ABI.
This information is given by the EF_MIPS_ABI2 (0x20) bit in the
e_flags field of the ELF header (a 4-byte value at offset 0x24 for
the here applicable ELFCLASS32).

See-also: ace3d65459
Signed-off-by: Andreas K. Hüttel 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: WANG Xuerui 


v5 changes are too different from v4 to keep these R-b tags IMO.

LGTM but I'd like Xuerui to double-check the R-b stands,
and an Acked-by from Laurent would make me feel safer ;)


This is just a squash of v4 patches, but I manually double-checked the 
definitions against elf.h for that extra confidence, and they looked 
good. The R-b tags still stand :)


--
WANG Xuerui
xe...@gentoo.org
Gentoo Linux developer
PGP: 7C52 19E3 26A0 7311 3EA3 8806 C01F 7214 BC93 1414



OpenPGP_0xC01F7214BC931414.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


[PATCH for-7.0 v2] target/mips: Fix address space range declaration on n32

2022-03-27 Thread WANG Xuerui
This bug is probably lurking there for so long, I cannot even git-blame
my way to the commit first introducing it.

Anyway, because n32 is also TARGET_MIPS64, the address space range
cannot be determined by looking at TARGET_MIPS64 alone. Fix this by only
declaring 48-bit address spaces for n64, or the n32 user emulation will
happily hand out memory ranges beyond the 31-bit limit and crash.

Confirmed to make the minimal reproducing example in the linked issue
behave.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/939
Signed-off-by: WANG Xuerui 
Cc: Philippe Mathieu-Daudé 
Cc: Aurelien Jarno 
Cc: Jiaxun Yang 
Cc: Aleksandar Rikalo 
Tested-by: Andreas K. Huettel 
Reviewed-by: Richard Henderson 
---

v2:
- Collect tags
- Make it clear this patch is for 7.0

 target/mips/cpu-param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h
index 9c4a6ea45e2..1aebd01df9c 100644
--- a/target/mips/cpu-param.h
+++ b/target/mips/cpu-param.h
@@ -12,7 +12,7 @@
 #else
 # define TARGET_LONG_BITS 32
 #endif
-#ifdef TARGET_MIPS64
+#ifdef TARGET_ABI_MIPSN64
 #define TARGET_PHYS_ADDR_SPACE_BITS 48
 #define TARGET_VIRT_ADDR_SPACE_BITS 48
 #else
-- 
2.35.1




Re: [PATCH v4 2/2] qemu-binfmt-conf.sh: Extend magic to distinguish mips o32 and n32 ABI

2022-03-27 Thread WANG Xuerui

On 3/24/22 07:05, Andreas K. Hüttel wrote:

This information is given by the EF_MIPS_ABI2 (0x20) bit in the
e_flags field of the ELF header (a 4-byte value at offset 0x24 for
the here applicable ELFCLASS32).

See-also: https://www.mail-archive.com/qemu-devel@nongnu.org/msg732572.html
Signed-off-by: Andreas K. Hüttel 
---
  scripts/qemu-binfmt-conf.sh | 16 
  1 file changed, 8 insertions(+), 8 deletions(-)


Reviewed-by: WANG Xuerui 

I have tested this myself, but I'd prefer others to take a look too.

--
WANG Xuerui
xe...@gentoo.org
Gentoo Linux developer
PGP: 7C52 19E3 26A0 7311 3EA3 8806 C01F 7214 BC93 1414




Re: [PATCH v4 1/2] qemu-binfmt-conf.sh: allow elf EI_ABIVERSION=1 for mips

2022-03-27 Thread WANG Xuerui

Hi Andreas,

On 3/24/22 07:05, Andreas K. Hüttel wrote:

With the command line flag -mplt and a recent toolchain, ELF binaries
generated by gcc can obtain EI_ABIVERSION=1, see below, which makes, e.g.,
gcc three-stage bootstrap in a mips-unknown-linux-gnu qemu-user chroot
fail since the binfmt-misc magic does not match anymore.

qemu executes these binaries just fine, so relax the mask slightly.

CHOST=mips-unknown-linux-gnu (and also mipsel-unknown-linux-gnu)
CFLAGS="-O2 -march=mips32 -mabi=32 -mplt -pipe"
gcc-11.2, binutils-2.37, glibc-2.34

|  /*
| - * ELF dump of './prev-gcc/build/gengenrtl'
| - * 29608 (0x73A8) bytes
| + * ELF dump of './gcc/build/gengenrtl'
| + * 54532 (0xD504) bytes
|   */
|
|  Elf32_Dyn dumpedelf_dyn_0[];
|  struct {
| Elf32_Ehdr ehdr;
| Elf32_Phdr phdrs[12];
| -   Elf32_Shdr shdrs[33];
| +   Elf32_Shdr shdrs[44];
| Elf32_Dyn *dyns;
|  } dumpedelf_0 = {
|
|  .ehdr = {
| .e_ident = { /* (EI_NIDENT bytes) */
| /* [0] EI_MAG:*/ 0x7F,'E','L','F',
| /* [4] EI_CLASS:  */ 1 , /* (ELFCLASS32) */
| /* [5] EI_DATA:   */ 2 , /* (ELFDATA2MSB) */
| /* [6] EI_VERSION:*/ 1 , /* (EV_CURRENT) */
| /* [7] EI_OSABI:  */ 0 , /* (ELFOSABI_NONE) */
| -   /* [8] EI_ABIVERSION: */ 0 ,
| +   /* [8] EI_ABIVERSION: */ 1 ,


It seems we could have more values than 0 or 1 here, according to 
binutils sources [1], so we might as well relax the mask for this byte...



| /* [9-15] EI_PAD: */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
| },
| .e_type  = 2  , /* (ET_EXEC) */
| .e_machine   = 8  , /* (EM_MIPS) */
| .e_version   = 1  , /* (EV_CURRENT) */
| (...)

Signed-off-by: Andreas K. Hüttel 
---
  scripts/qemu-binfmt-conf.sh | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index e9bfeb94d3..fc2f856800 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -61,11 +61,11 @@ m68k_family=m68k
  # FIXME: We could use the other endianness on a MIPS host.
  
  mips_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'

-mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'


... to just \x00, to allow any future MIPS libc ABI bumps. Libc ABI 
should not interfere with instruction semantics and emulation, so we're 
safe.



  mips_family=mips
  
  mipsel_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'

-mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
  mipsel_family=mips
  
  mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'




[1]: 
https://github.com/bminor/binutils-gdb/blob/binutils-2_38/bfd/elfxx-mips.c#L16691-L16739


--
WANG Xuerui
xe...@gentoo.org
Gentoo Linux developer
PGP: 7C52 19E3 26A0 7311 3EA3 8806 C01F 7214 BC93 1414




[PATCH] target/mips: Fix address space range declaration on n32

2022-03-26 Thread WANG Xuerui
This bug is probably lurking there for so long, I cannot even git-blame
my way to the commit first introducing it.

Anyway, because n32 is also TARGET_MIPS64, the address space range
cannot be determined by looking at TARGET_MIPS64 alone. Fix this by only
declaring 48-bit address spaces for n64, or the n32 user emulation will
happily hand out memory ranges beyond the 31-bit limit and crash.

Confirmed to make the minimal reproducing example in the linked issue
behave.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/939
Signed-off-by: WANG Xuerui 
Cc: Philippe Mathieu-Daudé 
Cc: Aurelien Jarno 
Cc: Jiaxun Yang 
Cc: Aleksandar Rikalo 
Cc: Andreas K. Hüttel 
---
 target/mips/cpu-param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h
index 9c4a6ea45e2..1aebd01df9c 100644
--- a/target/mips/cpu-param.h
+++ b/target/mips/cpu-param.h
@@ -12,7 +12,7 @@
 #else
 # define TARGET_LONG_BITS 32
 #endif
-#ifdef TARGET_MIPS64
+#ifdef TARGET_ABI_MIPSN64
 #define TARGET_PHYS_ADDR_SPACE_BITS 48
 #define TARGET_VIRT_ADDR_SPACE_BITS 48
 #else
-- 
2.35.1




[PATCH for-7.0] linux-user: Fix syscall parameter handling for MIPS n32

2022-03-20 Thread WANG Xuerui
The MIPS n32 ABI is basically n64 with the address space (i.e. pointer
width) shrinked to 32 bits. Meanwhile the current code treats it as
o32-like based on TARGET_ABI_BITS, which causes problems with n32
syscalls utilizing 64-bit offsets, like pread64, affecting most (if not
all) recently built n32 binaries.

This partially solves issue #909 ("qemu-mipsn32(el) user mode emulator
fails to execute any recently built n32 binaries"); with this change
applied, the built qemu-mipsn32el is able to progress beyond the
pread64, and finish _dl_start_user for the "getting ld.so load libc.so"
case. The program later dies with SIGBUS, though, due to _dl_start_user
not maintaining stack alignment after removing ld.so itself from argv,
and qemu-user starting to enforce alignment recently, but that is
orthogonal to the issue here; the more common case of chrooting is
working, verified with my own-built Gentoo n32 sysroot. (Depending on
the exact ISA used, one may have to explicitly specify QEMU_CPU, which
is the case for my chroot.)

Buglink: https://gitlab.com/qemu-project/qemu/-/issues/909
Signed-off-by: WANG Xuerui 
Cc: Laurent Vivier 
Cc: Philippe Mathieu-Daudé 
Cc: Jiaxun Yang 
Cc: Andreas K. Hüttel 
---

P.S. This patch is done with my Gentoo hat on, so I'm not using my
usual xen0n.name address. I'd like to add a mailmap entry for correct
shortlog display though, but it seems there's no category for "merely
preference" mappings yet. What should I do in this case?

 linux-user/user-internals.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index a8fdd6933b2..ee152ccfaa8 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -112,7 +112,7 @@ static inline int is_error(abi_long ret)
 return (abi_ulong)ret >= (abi_ulong)(-4096);
 }
 
-#if TARGET_ABI_BITS == 32
+#if (TARGET_ABI_BITS == 32) && !defined(TARGET_ABI_MIPSN32)
 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -121,7 +121,7 @@ static inline uint64_t target_offset64(uint32_t word0, 
uint32_t word1)
 return ((uint64_t)word1 << 32) | word0;
 #endif
 }
-#else /* TARGET_ABI_BITS == 32 */
+#else /* TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) */
 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
 {
 return word0;
@@ -136,7 +136,7 @@ static inline int regpairs_aligned(void *cpu_env, int num)
 {
 return CPUARMState *)cpu_env)->eabi) == 1) ;
 }
-#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32)
+#elif defined(TARGET_MIPS) && defined(TARGET_ABI_MIPSO32)
 static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
 /*
-- 
2.35.1




[PATCH] tcg/loongarch64: Fix fallout from recent MO_Q renaming

2022-02-06 Thread WANG Xuerui
From: WANG Xuerui 

Apparently we were left behind; just renaming MO_Q to MO_UQ is enough.

Fixes: fc313c64345453c7 ("exec/memop: Adding signedness to quad definitions")
Signed-off-by: WANG Xuerui 
---
 tcg/loongarch64/tcg-target.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 9cd46c9be3..d31a0e5991 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -871,7 +871,7 @@ static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg 
rd, TCGReg rj,
 case MO_SL:
 tcg_out_opc_ldx_w(s, rd, rj, rk);
 break;
-case MO_Q:
+case MO_UQ:
 tcg_out_opc_ldx_d(s, rd, rj, rk);
 break;
 default:
-- 
2.35.1




Re: [PATCH v14 02/26] target/loongarch: Add core definition

2022-01-12 Thread WANG Xuerui
Hi,

On 2022/1/12 18:17, gaosong wrote:
>
> Hi,
>
> On 2022/1/12 下午5:28, gaosong wrote:
 +    data = FIELD_DP32(data, CPUCFG16, L3_IUUNIFY, 1);
 +    data = FIELD_DP32(data, CPUCFG16, L3_IUINCL, 1);
 +    env->cpucfg[16] = data;
 +
 +    data = 0;
 +    data = FIELD_DP32(data, CPUCFG17, L1IU_WAYS, 0x8003);
>>>
>>> This seems out-of-place, according to the manual this field is Way-1
>>> for the L1I cache, so you have 0x8004=32772 ways in this cache?
>>>
>>> Same for all similar constructions below.
>>>
>> I have time to reply to your comment now.
>> As in the previous comments, I don't remember which one,these values should 
>> be the same as the values of the physical environment. I dumped 'CPUCFG17' 
>> value again,
>> the value is no problem. Maybe you didn't think about dumping these values 
>> when you commented. The value of  'L11U_SIZE' is dumped to be 0. and 
>> cpucfg[i] has been 
>> initialized to 0 before. There is no need to set it again.
> Not quite right,  cpucfg[17] is '0x6083', I missed a '0',  I don't know 
> from which version it's wrong
> Thank you very much,  if I hadn't dumped the value today, I wouldn't have 
> realized the wrong.  

Still not quite right; maybe you made a typo there as the value is
`0x06080003` (the fields are all whole bytes/shorts, so very easy to
recognize).

I used the following snippet to get real values from the 3A5000 system:

#include 

int cpucfg(const int sel)
{
    int ret;
    __asm__ __volatile__("cpucfg %0, %1" : "=r"(ret) : "r"(sel));
    return ret;
}

int main(void)
{
    int i;
    int c;
    for (i = 0; i < 64; i++) {
    c = cpucfg(i);
    if (!c) {
    continue;
    }
    printf("CPUCFG.0x%-2x = 0x%08x\n", i, c);
    }

    return 0;
}

And I got the following output so we can cross-check:

CPUCFG.0x0  = 0x0014c010
CPUCFG.0x1  = 0x03f2f2fe
CPUCFG.0x2  = 0x007ccfc7
CPUCFG.0x3  = 0xfcff
CPUCFG.0x4  = 0x05f5e100
CPUCFG.0x5  = 0x00010001
CPUCFG.0x6  = 0x7f33
CPUCFG.0x10 = 0x2c3d
CPUCFG.0x11 = 0x06080003
CPUCFG.0x12 = 0x06080003
CPUCFG.0x13 = 0x0608000f
CPUCFG.0x14 = 0x060e000f
CPUCFG.0x30 = 0x000e

Obviously the 0x30 leaf is undocumented, but not implementing it
shouldn't matter either, as userspace has no way to make use of that
when people aren't even aware of its existence. The other fields are of
course to be checked to only leave the implemented bits set in the QEMU
implementation.

Hope that helps!


Re: [PATCH v14 02/26] target/loongarch: Add core definition

2022-01-10 Thread WANG Xuerui

Hi,

On 1/10/22 20:34, gaosong wrote:


Hi,

On 2022/1/10 上午2:49, Richard Henderson wrote:

+static bool loongarch_cpu_has_work(CPUState *cs)
+{
+    return true;


Note: this is only applicable to CONFIG_USER_ONLY, and needs to be 
changed in the following commits adding system emulation. To better 
convey your intention it may be better to use an #ifdef guard, 
something like this:


#ifndef CONFIG_USER_ONLY
#error System emulation TODO
#else
 return true;
#endif

(I'm not sure if this is okay in QEMU coding style, so please 
correct me if this isn't the case.)



In my opinion, we don't need to do this. As you pointed out below, SPW 
shouldn't appear in this series. All CONFIG_USER_ONLY  macors should appear in 
the system emulation series.


IMO, preemptively including the guard serves as "paving the road" to the 
full system emulation; in your argument, I feel we're deferring too much 
information to the context (this patch being inside the "linux-user" 
series, and getting merged earlier than full system emulation), while 
context would gradually fade out in the months/years ahead; being 
precise in writing down what you mean doesn't do any harm.


Additionally, we might have to re-order the patches in order to unblock 
as much progress as possible, and in that case, this patch and the other 
patch adding the !CONFIG_USER_ONLY part would probably get squashed into 
one, so this code has to be touched too.


Re: [PATCH v14 02/26] target/loongarch: Add core definition

2022-01-10 Thread WANG Xuerui

Hi,

On 1/10/22 21:00, gaosong wrote:


Hi,

On 2022/1/9 下午5:25, WANG Xuerui wrote:

+
+const char * const fregnames[32] = {
+    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+    "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+static const char * const excp_names[EXCP_LAST + 1] = {
+    [EXCP_SYSCALL] = "Syscall",
+    [EXCP_BREAK] = "Break",
+    [EXCP_INE] = "Instruction Non-existent",
Nit: "Instruction Non-Existent" (or is there any authoritative source 
for this spelling? the English translation of the manual?) 

I must admit that your English is really good, But 'Instruction Non-existent' 
is what you pointed out in v7.  I have a history [1],
[1]https://patchew.org/QEMU/1634561247-25499-1-git-send-email-gaos...@loongson.cn/1634561247-25499-3-git-send-email-gaos...@loongson.cn/
> +static const char * const excp_names[EXCP_LAST + 1] = {
> +[EXCP_ADE] = "Address error",
> +[EXCP_SYSCALL] = "Syscall",
> +[EXCP_BREAK] = "Break",
> +[EXCP_INE] = "Inst. Not Exist",
Nit: "Instruction Non-existent", no need to shorten "instruction" like
this IMO; no other similar usages exist so this would not be consistent.
In any case thank you for your other suggestions.


Well, I do make my mistakes sometimes, and I'll explain a bit: in the 
former review what I noticed was the broken English, and I pointed that 
out, but meanwhile I've forgotten I had done that, and why I didn't 
write "Non-Existent" was because the "Address error" wasn't in full 
Title Case. However, in this revision, what I noticed is the 
inconsistent casing (with EXCP_ADE removed, all other strings are in 
Title Case now), hence the reply.


No need to go full self-defense over this; I think what matters after 
all is just consistency.




Thanks
Song

Re: [RFC PATCH v4 08/30] target/loongarch: Add LoongArch IOCSR instruction

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This includes:
- IOCSR{RD/WR}.{B/H/W/D}

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/cpu.c   |   8 ++
  target/loongarch/cpu.h   |   4 +
  target/loongarch/disas.c |   8 ++
  target/loongarch/helper.h|   2 +
  target/loongarch/insn_trans/trans_core.c.inc | 103 
  target/loongarch/insns.decode|   9 ++
  target/loongarch/iocsr_helper.c  | 120 +++
  target/loongarch/meson.build |   1 +
  8 files changed, 255 insertions(+)
  create mode 100644 target/loongarch/iocsr_helper.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 780eb96a3c..571092ce53 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -158,6 +158,14 @@ static void loongarch_3a5000_initfn(Object *obj)
  env->cpucfg[20] = data;
  
  env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);

+
+#ifndef CONFIG_USER_ONLY
+env->address_space_iocsr = g_malloc(sizeof(*env->address_space_iocsr));
+env->system_iocsr = g_malloc(sizeof(*env->system_iocsr));
+memory_region_init_io(env->system_iocsr, obj, NULL,
+  env, "iocsr", UINT64_MAX);
+address_space_init(env->address_space_iocsr, env->system_iocsr, "IOCSR");
+#endif
  }
  
  static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 2a1841a708..ddb69ffecf 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -151,6 +151,7 @@ extern const char * const fregnames[32];
  
  #define N_IRQS  14

  #define IRQ_TIMER   11
+#define IRQ_IPI 12
  
  #define LOONGARCH_TLB_MAX  (2048 + 64) /* 2048 STLB + 64 MTLB */

  #define LOONGARCH_STLB 2048 /* 2048 STLB */
@@ -257,6 +258,9 @@ struct CPULoongArchState {
  
  #ifndef CONFIG_USER_ONLY

  LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
+
+AddressSpace *address_space_iocsr;
+MemoryRegion *system_iocsr;
  #endif
  };
  
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c

index de683bb88b..cbb264a318 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -531,6 +531,14 @@ INSN(bgeu, rr_offs)
  INSN(csrrd,r_csr)
  INSN(csrwr,r_csr)
  INSN(csrxchg,  rr_csr)
+INSN(iocsrrd_b,rr)
+INSN(iocsrrd_h,rr)
+INSN(iocsrrd_w,rr)
+INSN(iocsrrd_d,rr)
+INSN(iocsrwr_b,rr)
+INSN(iocsrwr_h,rr)
+INSN(iocsrwr_w,rr)
+INSN(iocsrwr_d,rr)
  
  #define output_fcmp(C, PREFIX, SUFFIX) \

  { 
 \
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 036dbf31f8..1bcd082858 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -98,4 +98,6 @@ DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, 
env, i32)
  DEF_HELPER_2(csr_rdq, i64, env, i64)
  DEF_HELPER_3(csr_wrq, i64, env, tl, i64)
  DEF_HELPER_4(csr_xchgq, i64, env, tl, tl, i64)
+DEF_HELPER_3(iocsr_read, i64, env, tl, i32)
+DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
  #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 7d2cfe3534..592d2a339e 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -20,6 +20,14 @@ static bool trans_##name(DisasContext *ctx, arg_##name * a)  
\
  GEN_FALSE_TRANS(csrrd)
  GEN_FALSE_TRANS(csrwr)
  GEN_FALSE_TRANS(csrxchg)
+GEN_FALSE_TRANS(iocsrrd_b)
+GEN_FALSE_TRANS(iocsrrd_h)
+GEN_FALSE_TRANS(iocsrrd_w)
+GEN_FALSE_TRANS(iocsrrd_d)
+GEN_FALSE_TRANS(iocsrwr_b)
+GEN_FALSE_TRANS(iocsrwr_h)
+GEN_FALSE_TRANS(iocsrwr_w)
+GEN_FALSE_TRANS(iocsrwr_d)
  
  #else
  
@@ -120,4 +128,99 @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a)

  return true;
  }
  
+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a)

+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(1));
+return true;
+}
+
+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(2));
+return true;
+}
+
+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(4));
+return true;
+}
+

Re: [RFC PATCH v4 00/30] Add LoongArch softmmu support.

2022-01-09 Thread WANG Xuerui

Hi Xiaojuan,

I've just finished reviewing the first part (target modifications) as 
I'm not familiar with QEMU device emulation. You may have to revise the 
target part carefully, and re-organize at the series level to accelerate 
upstreaming though, as Richard pointed out in the other patch series 
(Song Gao's LoongArch linux-user support series) that the series as a 
whole is blocked.



On 1/8/22 17:13, Xiaojuan Yang wrote:

This series patch add softmmu support for LoongArch.
Base on the linux-user emulation support V14 patch.
   *https://patchew.org/QEMU/20220106094200.1801206-1-gaos...@loongson.cn/


There's a recognized syntax for marking patch series dependency [1], so 
that your series could be auto-applied by Patchew for ease of 
consumption. You can look at Song Gao's v14 LoongArch linux-user series 
for example usage.


[1]: 
https://www.qemu.org/docs/master/devel/submitting-a-patch.html#base-patches-against-current-git-master



The latest kernel:
   *https://github.com/loongson/linux/tree/loongarch-next
The latest uefi:
   *https://github.com/loongson/edk2
   *https://github.com/loongson/edk2-platforms
The manual:
   *https://github.com/loongson/LoongArch-Documentation/releases/tag/2021.10.11


Changes for v4:
1. Uefi code is open and add some fdt interface to pass info between qemu and 
uefi.
2. Use a per cpu address space for iocsr.
3. Modify the tlb emulation.
4. Machine and board code mainly follow Mark's advice.
5. Adjust pci host space map.
6. Use more memregion to simplify the interrupt controller's emulate.


Changes for v3:
1.Target code mainly follow Richard's code review comments.
2.Put the csr and iocsr read/write instruction emulate into 2 different patch.
3.Simply the tlb emulation.
4.Delete some unused csr registers defintion.
5.Machine and board code mainly follow Mark's advice, discard the obsolete 
interface.
6.NUMA function is removed for it is not completed.
7.Adjust some format problem and the Naming problem


Changes for v2:
1.Combine patch 2 and 3 into one.
2.Adjust the order of the patch.
3.Put all the binaries on the github.
4.Modify some emulate errors when use the kernel from the github.
5.Adjust some format problem and the Naming problem
6.Others mainly follow Richard's code review comments.

Please help review!

Thanks

Xiaojuan Yang (30):
   target/loongarch: Update README
   target/loongarch: Add CSR registers definition
   target/loongarch: Add basic vmstate description of CPU.


There are serious issues with your commit message...

First of all, some of your commit message titles end with a period, 
while some don't; the QEMU convention is to NOT use one. So please fix 
all commits like this to remove the trailing period.



   target/loongarch: Implement qmp_query_cpu_definitions()
   target/loongarch: Add constant timer support

"Implement the constant timer" would be more concise and idiomatic English.

   target/loongarch: Add MMU support for LoongArch CPU.
   target/loongarch: Add LoongArch CSR instruction
   target/loongarch: Add LoongArch IOCSR instruction
You don't need to emphasize "LoongArch" because the component prefix 
"target/loongarch" says it all. Also all of these commits add support 
for multiple instructions at once, so you would say "instructions". You 
may need to check all places for simple plural form mistakes like these.

   target/loongarch: Add TLB instruction support
   target/loongarch: Add other core instructions support
   target/loongarch: Add LoongArch interrupt and exception handle

"handlers"?

   target/loongarch: Add timer related instructions support.
   target/loongarch: Add gdb support.
   hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3
 Platform
"Add the LS7A1000 PCIe host bridge" would be enough; although currently 
the LS7A chip is only paired with Loongson 3 CPUs, there's no intrinsic 
reasons to only support this combination ever.

   hw/loongarch: Add support loongson3-ls7a machine type.

"Support the loongson3-ls7a machine type"

   hw/loongarch: Add LoongArch cpu interrupt support(CPUINTC)
You may just say "Implement the LoongArch CPUINTC"; people naturally 
look in the diff to get what CPUINTC means. Same for other following 
commits with similar commit messages.

   hw/loongarch: Add LoongArch ipi interrupt support(IPI)
   hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)
   hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI)
   hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)
   hw/loongarch: Add irq hierarchy for the system
   Enable common virtio pci support for LoongArch

This patch is missing component prefix in its title.

   hw/loongarch: Add some devices support for 3A5000.
What's "some"? You may want to clarify a bit, or to split patches if you 
cannot make your title short and concise.

   hw/loongarch: Add LoongArch ls7a rtc device support
The LS7A RTC is usable for MIPS-based Loongson systems too, like the 
3A4000/LS7A1000 

Re: [RFC PATCH v4 03/30] target/loongarch: Add basic vmstate description of CPU.

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This patch introduce vmstate_loongarch_cpu

Again, pointless commit message.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
Reviewed-by: Richard Henderson
---
  target/loongarch/cpu.c   |  3 ++
  target/loongarch/internals.h |  4 ++
  target/loongarch/machine.c   | 84 
  target/loongarch/meson.build |  6 +++
  4 files changed, 97 insertions(+)
  create mode 100644 target/loongarch/machine.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index ed03ec2986..6e3dc5e6fa 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -320,6 +320,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
  cc->has_work = loongarch_cpu_has_work;
  cc->dump_state = loongarch_cpu_dump_state;
  cc->set_pc = loongarch_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+dc->vmsd = _loongarch_cpu;
+#endif
  cc->disas_set_info = loongarch_cpu_disas_set_info;
  #ifdef CONFIG_TCG
  cc->tcg_ops = _tcg_ops;
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 774a87ec80..c8e6f7012c 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -25,4 +25,8 @@ const char *loongarch_exception_name(int32_t exception);
  
  void restore_fp_status(CPULoongArchState *env);
  
+#ifndef CONFIG_USER_ONLY

+extern const VMStateDescription vmstate_loongarch_cpu;
+#endif
+
  #endif
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
new file mode 100644
index 00..b9effe6db2
--- /dev/null
+++ b/target/loongarch/machine.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch machine State

Use consistent casing; "machine state" or "Machine State".

+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+
+/* LoongArch CPU state */
+
+const VMStateDescription vmstate_loongarch_cpu = {
+.name = "cpu",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+
+VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
+VMSTATE_UINTTL(env.pc, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.fpr, LoongArchCPU, 32),
+VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
+
+/* Remaining CSR registers */

"Remaining CSRs"

+VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CPUID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
+VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
+

Re: [RFC PATCH v4 09/30] target/loongarch: Add TLB instruction support

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This includes:
- TLBSRCH
- TLBRD
- TLBWR
- TLBFILL
- TLBCLR
- TLBFLUSH
- INVTLB

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/disas.c |  17 +
  target/loongarch/helper.h|  12 +
  target/loongarch/insn_trans/trans_core.c.inc | 112 ++
  target/loongarch/insns.decode|  11 +
  target/loongarch/tlb_helper.c| 364 +++
  5 files changed, 516 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index cbb264a318..483270f331 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -216,6 +216,16 @@ static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
  output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->csr);
  }
  
+static void output_empty(DisasContext *ctx, arg_empty *a,

+ const char *mnemonic)
+{
Isn't this missing an output altogether so you don't even have mnemonic 
output?

+}
+
+static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
+}
+
  #define INSN(insn, type)\
  static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
  {   \
@@ -539,6 +549,13 @@ INSN(iocsrwr_b,rr)
  INSN(iocsrwr_h,rr)
  INSN(iocsrwr_w,rr)
  INSN(iocsrwr_d,rr)
+INSN(tlbsrch,  empty)
+INSN(tlbrd,empty)
+INSN(tlbwr,empty)
+INSN(tlbfill,  empty)
+INSN(tlbclr,   empty)
+INSN(tlbflush, empty)
+INSN(invtlb,   i_rr)
  
  #define output_fcmp(C, PREFIX, SUFFIX) \

  { 
 \
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 1bcd082858..97af7ac8aa 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -100,4 +100,16 @@ DEF_HELPER_3(csr_wrq, i64, env, tl, i64)
  DEF_HELPER_4(csr_xchgq, i64, env, tl, tl, i64)
  DEF_HELPER_3(iocsr_read, i64, env, tl, i32)
  DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
+
+DEF_HELPER_1(tlbwr, void, env)
+DEF_HELPER_1(tlbfill, void, env)
+DEF_HELPER_1(tlbsrch, void, env)
+DEF_HELPER_1(tlbrd, void, env)
+DEF_HELPER_1(tlbclr, void, env)
+DEF_HELPER_1(tlbflush, void, env)
+DEF_HELPER_1(invtlb_all, void, env)
+DEF_HELPER_2(invtlb_all_g, void, env, i32)
+DEF_HELPER_2(invtlb_all_asid, void, env, tl)
+DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
+DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
  #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 592d2a339e..5a8e9e0643 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -28,6 +28,13 @@ GEN_FALSE_TRANS(iocsrwr_b)
  GEN_FALSE_TRANS(iocsrwr_h)
  GEN_FALSE_TRANS(iocsrwr_w)
  GEN_FALSE_TRANS(iocsrwr_d)
+GEN_FALSE_TRANS(tlbsrch)
+GEN_FALSE_TRANS(tlbrd)
+GEN_FALSE_TRANS(tlbwr)
+GEN_FALSE_TRANS(tlbfill)
+GEN_FALSE_TRANS(tlbclr)
+GEN_FALSE_TRANS(tlbflush)
+GEN_FALSE_TRANS(invtlb)
  
  #else
  
@@ -223,4 +230,109 @@ static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a)

  gen_helper_iocsr_write(cpu_env, addr, val, tcg_constant_i32(8));
  return true;
  }
+
+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbsrch(cpu_env);
+return true;
+}
+
+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbrd(cpu_env);
+return true;
+}
+
+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbwr(cpu_env);
+
+if (ctx->mem_idx != MMU_DA_IDX) {
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+}
+return true;
+}
+
+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbfill(cpu_env);
+
+if (ctx->mem_idx != MMU_DA_IDX) {
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+}
+return true;
+}
+
+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbclr(cpu_env);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbflush(cpu_env);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool 

Re: [RFC PATCH v4 13/30] target/loongarch: Add gdb support.

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:14, Xiaojuan Yang wrote:

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  configs/targets/loongarch64-softmmu.mak |  1 +
  gdb-xml/loongarch-base64.xml| 43 +++
  gdb-xml/loongarch-fpu64.xml | 57 +++
  target/loongarch/cpu.c  |  7 ++
  target/loongarch/gdbstub.c  | 97 +
  target/loongarch/internals.h| 10 +++
  target/loongarch/meson.build|  1 +
  7 files changed, 216 insertions(+)
  create mode 100644 configs/targets/loongarch64-softmmu.mak
  create mode 100644 gdb-xml/loongarch-base64.xml
  create mode 100644 gdb-xml/loongarch-fpu64.xml
  create mode 100644 target/loongarch/gdbstub.c

diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
new file mode 100644
index 00..f33fa1590b
--- /dev/null
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -0,0 +1 @@
+TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml
diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml
new file mode 100644
index 00..f2af2a4b6e
--- /dev/null
+++ b/gdb-xml/loongarch-base64.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml
new file mode 100644
index 00..e52cf89fbc
--- /dev/null
+++ b/gdb-xml/loongarch-fpu64.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+  
+
+
+  
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
I know this file is copied from binutils, but aren't FCC registers 1-bit 
each? They are just predicates after all... Clarification from Loongson 
toolchain people would be appreciated.

+  
+
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index caab59b83a..8d0be47d4b 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -146,11 +146,18 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
   " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__,
   env->pc, env->CSR_ERA, env->CSR_TLBRERA, name);
  }
+if (cs->exception_index == EXCCODE_INT &&
+   (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))) {
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1);
+goto set_DERA;
+}
  
  switch (cs->exception_index) {

  case EXCCODE_DBP:
  env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1);
  env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC);
+goto set_DERA;
+set_DERA:
  env->CSR_DERA = env->pc;
  env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
  env->pc = env->CSR_EENTRY + 0x480;
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
new file mode 100644
index 00..2fec9364de
--- /dev/null
+++ b/target/loongarch/gdbstub.c
@@ -0,0 +1,97 @@
+/*
+ * LOONGARCH gdb server stub
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/gdbstub.h"
+#include "exec/helper-proto.h"
+
+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+
+if (0 <= n && n < 32) {
+return gdb_get_regl(mem_buf, env->gpr[n]);
+} else if (n == 32) {
+return gdb_get_regl(mem_buf, env->pc);
+}
+return 0;
+}
+
+int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+target_ulong tmp = ldtul_p(mem_buf);
+
+if (0 <= n && n < 32) {
+return env->gpr[n] = tmp, sizeof(target_ulong);
+} else if (n == 32) {
+return env->pc = tmp, sizeof(target_ulong);
+}
+return 0;
+}
+
+static int loongarch_gdb_get_fpu(CPULoongArchState *env,
+ GByteArray *mem_buf, int n)
+{
+if (0 <= n && n < 32) {
+return gdb_get_reg64(mem_buf, env->fpr[n]);
+} else if (32 <= n && n < 40) {
+return gdb_get_reg8(mem_buf, env->cf[n - 32]);
+} else if (n == 40) {
+return gdb_get_reg32(mem_buf, env->fcsr0);
+}
+return 0;
+}
+
+static int loongarch_gdb_set_fpu(CPULoongArchState *env,
+ uint8_t *mem_buf, int n)
+{
+if (0 <= n && n < 32) {
+return env->fpr[n] = ldq_p(mem_buf), 8;
+} else if (32 <= n && n < 40) {
+return env->cf[n - 32] = ldub_p(mem_buf), 1;
+} else if (n == 40) {
+return env->fcsr0 = ldl_p(mem_buf), 4;
+}
+return 0;
+}
+
+void 

Re: [RFC PATCH v4 05/30] target/loongarch: Add constant timer support

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/constant_timer.c | 63 +++
  target/loongarch/cpu.c|  9 +
  target/loongarch/cpu.h| 10 +
  target/loongarch/meson.build  |  1 +
  4 files changed, 83 insertions(+)
  create mode 100644 target/loongarch/constant_timer.c

diff --git a/target/loongarch/constant_timer.c 
b/target/loongarch/constant_timer.c
new file mode 100644
index 00..e7d0f5ffe7
--- /dev/null
+++ b/target/loongarch/constant_timer.c
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch constant timer support
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/loongarch/loongarch.h"
+#include "qemu/timer.h"
+#include "cpu.h"
+
+#define TIMER_PERIOD10 /* 10 ns period for 100 Mhz frequency */

"MHz"

+#define CONSTANT_TIMER_TICK_MASK0xfffcUL
+#define CONSTANT_TIMER_ENABLE   0x1UL
+
+/* LoongArch timer */
Looks like this comment is for some type definitions, but the function 
below is just an accessor, so remove it? The whole file is about the 
"LoongArch timer" after all.

+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu)
+{
+return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD;
+}
+
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu)
+{
+uint64_t now, expire;
+
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+expire = timer_expire_time_ns(>timer);
+
+return (expire - now) / TIMER_PERIOD;
+}
+
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value)
+{
+CPULoongArchState *env = >env;
+uint64_t now, next;
+
+env->CSR_TCFG = value;
+if (value & CONSTANT_TIMER_ENABLE) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(>timer, next);
+}
+}
+
+void loongarch_constant_timer_cb(void *opaque)
+{
+LoongArchCPU *cpu  = opaque;
+CPULoongArchState *env = >env;
+uint64_t now, next;
+
+if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(>timer, next);
+} else {
+env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
+}
+
+env->CSR_ESTAT |= 1 << IRQ_TIMER;
+cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 690eeea2e6..823951 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -235,12 +235,21 @@ static void loongarch_cpu_realizefn(DeviceState *dev, 
Error **errp)
  LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev);
  Error *local_err = NULL;
  
+#ifndef CONFIG_USER_ONLY

+LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+#endif
+
  cpu_exec_realizefn(cs, _err);
  if (local_err != NULL) {
  error_propagate(errp, local_err);
  return;
  }
  
+#ifndef CONFIG_USER_ONLY

+timer_init_ns(>timer, QEMU_CLOCK_VIRTUAL,
+  _constant_timer_cb, cpu);
+#endif
+
  cpu_reset(cs);
  qemu_init_vcpu(cs);
  
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h

index cf7fc46f72..ef84584678 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -12,6 +12,7 @@
  #include "fpu/softfloat-types.h"
  #include "hw/registerfields.h"
  #include "cpu-csr.h"
+#include "qemu/timer.h"
  
  #define TCG_GUEST_DEFAULT_MO (0)
  
@@ -148,6 +149,9 @@ FIELD(CPUCFG20, L3IU_SIZE, 24, 7)

  extern const char * const regnames[32];
  extern const char * const fregnames[32];
  
+#define N_IRQS  14

+#define IRQ_TIMER   11
+
  typedef struct CPULoongArchState CPULoongArchState;
  struct CPULoongArchState {
  uint64_t gpr[32];
@@ -242,6 +246,7 @@ struct LoongArchCPU {
  
  CPUNegativeOffsetState neg;

  CPULoongArchState env;
+QEMUTimer timer; /* Internal timer */
What do you mean by "internal", is there any "external" counterpart? If 
there isn't one, I think you may be referring to the "architectural" 
timer instead (as is defined by LoongArch, instead of any concrete 
implementation), and this would have to be changed accordingly.

  };
  
  #define TYPE_LOONGARCH_CPU "loongarch-cpu"

@@ -306,4 +311,9 @@ enum {
  #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
  #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
  
+void loongarch_constant_timer_cb(void *opaque);

+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value);
  #endif /* 

Re: [RFC PATCH v4 04/30] target/loongarch: Implement qmp_query_cpu_definitions()

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This patch introduce qmp_query_cpu_definitions interface.


"implments"; however the whole sentence becomes nearly identical to the 
title, so it's better to remove this sentence after all.



Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
Reviewed-by: Richard Henderson
---
  qapi/machine-target.json |  6 --
  target/loongarch/cpu.c   | 26 ++
  2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f5ec4bc172..682dc86b42 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -324,7 +324,8 @@
 'TARGET_ARM',
 'TARGET_I386',
 'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
  
  ##

  # @query-cpu-definitions:
@@ -340,4 +341,5 @@
 'TARGET_ARM',
 'TARGET_I386',
 'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 6e3dc5e6fa..690eeea2e6 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -351,3 +351,29 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
  };
  
  DEFINE_TYPES(loongarch_cpu_type_infos)

+
+static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CpuDefinitionInfoList **cpu_list = user_data;
+CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
+const char *typename = object_class_get_name(oc);
+
+info->name = g_strndup(typename,
+   strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU));
+info->q_typename = g_strdup(typename);
+
+QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+GSList *list;
+
+list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
+g_slist_foreach(list, loongarch_cpu_add_definition, _list);
+g_slist_free(list);
+
+return cpu_list;
+}


After removing the commit message body:

Reviewed-by: WANG Xuerui 




Re: [RFC PATCH v4 07/30] target/loongarch: Add LoongArch CSR instruction

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This includes:
- CSRRD
- CSRWR
- CSRXCHG

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/cpu.h   |  88 +
  target/loongarch/csr_helper.c| 112 +
  target/loongarch/disas.c |  15 +++
  target/loongarch/helper.h|   7 ++
  target/loongarch/insn_trans/trans_core.c.inc | 123 +++
  target/loongarch/insns.decode|  13 ++
  target/loongarch/meson.build |   1 +
  target/loongarch/translate.c |   5 +
  8 files changed, 364 insertions(+)
  create mode 100644 target/loongarch/csr_helper.c
  create mode 100644 target/loongarch/insn_trans/trans_core.c.inc

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 232d51e788..2a1841a708 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -260,6 +260,94 @@ struct CPULoongArchState {
  #endif
  };
  
+#define CSR_OFF(X)  \

+   [LOONGARCH_CSR_##X] = offsetof(CPULoongArchState, CSR_##X)
+#define CSR_OFF_ARRAY(X, N)  \
+   [LOONGARCH_CSR_##X(N)] = offsetof(CPULoongArchState, CSR_##X[N])
+
+static const int csr_offsets[] = {
+ CSR_OFF(CRMD),
+ CSR_OFF(PRMD),
+ CSR_OFF(EUEN),
+ CSR_OFF(MISC),
+ CSR_OFF(ECFG),
+ CSR_OFF(ESTAT),
+ CSR_OFF(ERA),
+ CSR_OFF(BADV),
+ CSR_OFF(BADI),
+ CSR_OFF(EENTRY),
+ CSR_OFF(TLBIDX),
+ CSR_OFF(TLBEHI),
+ CSR_OFF(TLBELO0),
+ CSR_OFF(TLBELO1),
+ CSR_OFF(ASID),
+ CSR_OFF(PGDL),
+ CSR_OFF(PGDH),
+ CSR_OFF(PGD),
+ CSR_OFF(PWCL),
+ CSR_OFF(PWCH),
+ CSR_OFF(STLBPS),
+ CSR_OFF(RVACFG),
+ CSR_OFF(CPUID),
+ CSR_OFF(PRCFG1),
+ CSR_OFF(PRCFG2),
+ CSR_OFF(PRCFG3),
+ CSR_OFF_ARRAY(SAVE, 0),
+ CSR_OFF_ARRAY(SAVE, 1),
+ CSR_OFF_ARRAY(SAVE, 2),
+ CSR_OFF_ARRAY(SAVE, 3),
+ CSR_OFF_ARRAY(SAVE, 4),
+ CSR_OFF_ARRAY(SAVE, 5),
+ CSR_OFF_ARRAY(SAVE, 6),
+ CSR_OFF_ARRAY(SAVE, 7),
+ CSR_OFF_ARRAY(SAVE, 8),
+ CSR_OFF_ARRAY(SAVE, 9),
+ CSR_OFF_ARRAY(SAVE, 10),
+ CSR_OFF_ARRAY(SAVE, 11),
+ CSR_OFF_ARRAY(SAVE, 12),
+ CSR_OFF_ARRAY(SAVE, 13),
+ CSR_OFF_ARRAY(SAVE, 14),
+ CSR_OFF_ARRAY(SAVE, 15),
+ CSR_OFF(TID),
+ CSR_OFF(TCFG),
+ CSR_OFF(TVAL),
+ CSR_OFF(CNTC),
+ CSR_OFF(TICLR),
+ CSR_OFF(LLBCTL),
+ CSR_OFF(IMPCTL1),
+ CSR_OFF(IMPCTL2),
+ CSR_OFF(TLBRENTRY),
+ CSR_OFF(TLBRBADV),
+ CSR_OFF(TLBRERA),
+ CSR_OFF(TLBRSAVE),
+ CSR_OFF(TLBRELO0),
+ CSR_OFF(TLBRELO1),
+ CSR_OFF(TLBREHI),
+ CSR_OFF(TLBRPRMD),
+ CSR_OFF(MERRCTL),
+ CSR_OFF(MERRINFO1),
+ CSR_OFF(MERRINFO2),
+ CSR_OFF(MERRENTRY),
+ CSR_OFF(MERRERA),
+ CSR_OFF(MERRSAVE),
+ CSR_OFF(CTAG),
+ CSR_OFF_ARRAY(DMW, 0),
+ CSR_OFF_ARRAY(DMW, 1),
+ CSR_OFF_ARRAY(DMW, 2),
+ CSR_OFF_ARRAY(DMW, 3),
+ CSR_OFF(DBG),
+ CSR_OFF(DERA),
+ CSR_OFF(DSAVE),
+};
+
+static inline int cpu_csr_offset(unsigned csr_num)
+{
+if (csr_num < ARRAY_SIZE(csr_offsets)) {
+return csr_offsets[csr_num];
+}
+return 0;
+}
+
  /**
   * LoongArchCPU:
   * @env: #CPULoongArchState
diff --git a/target/loongarch/csr_helper.c b/target/loongarch/csr_helper.c
new file mode 100644
index 00..4d0619cec8
--- /dev/null
+++ b/target/loongarch/csr_helper.c
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for csr registers

"Emulation helpers for CSRs" is enough.

+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "internals.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "hw/irq.h"
+#include "cpu-csr.h"
+#include "hw/loongarch/loongarch.h"
+#include "tcg/tcg-ldst.h"
+
+target_ulong helper_csr_rdq(CPULoongArchState *env, uint64_t csr)
+{
+LoongArchCPU *cpu;
+int64_t v;
+
+switch (csr) {
+case LOONGARCH_CSR_PGD:
+if (env->CSR_TLBRERA & 0x1) {
+v = env->CSR_TLBRBADV;
+} else {
+v = env->CSR_BADV;
+}
+
+if ((v >> 63) & 0x1) {
+v = env->CSR_PGDH;
+} else {
+v = env->CSR_PGDL;
+}
+break;
+case LOONGARCH_CSR_CPUID:
+v = (env_cpu(env))->cpu_index;
+break;
+case LOONGARCH_CSR_TVAL:
+cpu = LOONGARCH_CPU(env_cpu(env));
+v = cpu_loongarch_get_constant_timer_ticks(cpu);
+break;
+default:
+break;
+}
+
+return v;
+}
+
+target_ulong helper_csr_wrq(CPULoongArchState *env, target_ulong val,
+uint64_t csr)
+{
+LoongArchCPU *cpu;
+int64_t old_v = -1;
+
+switch (csr) {
+case LOONGARCH_CSR_ESTAT:
+/* Only IS[1:0] can be write */
+

Re: [RFC PATCH v4 06/30] target/loongarch: Add MMU support for LoongArch CPU.

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This patch introduces basic TLB interfaces.

Same comment regarding commit messages adding little information.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/cpu-param.h  |   2 +-
  target/loongarch/cpu.c|  32 
  target/loongarch/cpu.h|  45 -
  target/loongarch/internals.h  |  10 ++
  target/loongarch/machine.c|  17 ++
  target/loongarch/meson.build  |   1 +
  target/loongarch/op_helper.c  |   8 +
  target/loongarch/tlb_helper.c | 326 ++
  8 files changed, 439 insertions(+), 2 deletions(-)
  create mode 100644 target/loongarch/tlb_helper.c

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
index 9a769b67e0..414d8fff46 100644
--- a/target/loongarch/cpu-param.h
+++ b/target/loongarch/cpu-param.h
@@ -13,6 +13,6 @@
  #define TARGET_VIRT_ADDR_SPACE_BITS 48
  
  #define TARGET_PAGE_BITS 14

-#define NB_MMU_MODES 4
+#define NB_MMU_MODES 5
  
  #endif

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 823951..780eb96a3c 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -237,6 +237,7 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error 
**errp)
  
  #ifndef CONFIG_USER_ONLY

  LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+CPULoongArchState *env = >env;
  #endif
  
  cpu_exec_realizefn(cs, _err);

@@ -248,6 +249,7 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error 
**errp)
  #ifndef CONFIG_USER_ONLY
  timer_init_ns(>timer, QEMU_CLOCK_VIRTUAL,
_constant_timer_cb, cpu);
+loongarch_mmu_init(env);
  #endif
  
  cpu_reset(cs);

@@ -295,6 +297,23 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
  }
  }
  
+#ifndef CONFIG_USER_ONLY

+qemu_fprintf(f, "EUEN=%016" PRIx64 "\n", env->CSR_EUEN);

Why EUEN first and generally not in the structure definition/manual order?

+qemu_fprintf(f, "ESTAT=%016" PRIx64 "\n", env->CSR_ESTAT);
+qemu_fprintf(f, "ERA=%016" PRIx64 "\n", env->CSR_ERA);
+qemu_fprintf(f, "CRMD=%016" PRIx64 "\n", env->CSR_CRMD);
+qemu_fprintf(f, "PRMD=%016" PRIx64 "\n", env->CSR_PRMD);
+qemu_fprintf(f, "BadVAddr=%016" PRIx64 "\n", env->CSR_BADV);
The register is named just "BADV" in the manuals, "BadVAddr" seems like 
MIPS leftover...

+qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY);
+qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
+qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
+qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
+qemu_fprintf(f, "BadInstr=%016" PRIx64 "\n", env->CSR_BADI);

Also this; "BadInstr" also comes from MIPS IIRC.

+qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 ","
+ " PRCFG3=%016" PRIx64 "\n",
+ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3);
+#endif
+
  /* fpr */
  if (flags & CPU_DUMP_FPU) {
  for (i = 0; i < 32; i++) {
@@ -312,9 +331,21 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
  static struct TCGCPUOps loongarch_tcg_ops = {
  .initialize = loongarch_translate_init,
  .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
+
+#if !defined(CONFIG_USER_ONLY)
+.tlb_fill = loongarch_cpu_tlb_fill,
+#endif /* !CONFIG_USER_ONLY */
  };
  #endif /* CONFIG_TCG */
  
+#ifndef CONFIG_USER_ONLY

+#include "hw/core/sysemu-cpu-ops.h"
+
+static const struct SysemuCPUOps loongarch_sysemu_ops = {
+.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
+};
+#endif
+
  static void loongarch_cpu_class_init(ObjectClass *c, void *data)
  {
  LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
@@ -331,6 +362,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
  cc->set_pc = loongarch_cpu_set_pc;
  #ifndef CONFIG_USER_ONLY
  dc->vmsd = _loongarch_cpu;
+cc->sysemu_ops = _sysemu_ops;
  #endif
  cc->disas_set_info = loongarch_cpu_disas_set_info;
  #ifdef CONFIG_TCG
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ef84584678..232d51e788 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -152,6 +152,29 @@ extern const char * const fregnames[32];
  #define N_IRQS  14
  #define IRQ_TIMER   11
  
+#define LOONGARCH_TLB_MAX  (2048 + 64) /* 2048 STLB + 64 MTLB */

+#define LOONGARCH_STLB 2048 /* 2048 STLB */
+#define LOONGARCH_MTLB 64   /* 64 MTLB */
Why not define LOONGARCH_TLB_MAX after the two individual definitions, 
and just say "#define LOONGARCH_TLB_MAX (LOONGARCH_STLB + 
LOONGARCH_MTLB)" to really eliminate the duplication?

+
+/*
+ * define the ASID PS E VPPN field of TLB
+ *
+ * PS of stlb come from stlbps.ps
+ * PS of mtlb come from tlbidx.ps
+ */
I can't understand this comment, which seems like just describing what 
the following code literally meant. Might remove as well...

+FIELD(TLB_MISC, E, 0, 1)

Re: [RFC PATCH v4 02/30] target/loongarch: Add CSR registers definition

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

1.Define All the CSR registers and its field.
2.Set some default csr values.
Unnecessary explanation; the code addition itself should be obvious 
enough as to its intention.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/cpu-csr.h | 236 +
  target/loongarch/cpu.c |  35 ++
  target/loongarch/cpu.h |  57 +
  3 files changed, 328 insertions(+)
  create mode 100644 target/loongarch/cpu-csr.h

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
new file mode 100644
index 00..7a57b7ea36
--- /dev/null
+++ b/target/loongarch/cpu-csr.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CPU CSR registers
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_CSR_H
+#define LOONGARCH_CPU_CSR_H
+
+/* Base on: kernal: arch/loongarch/include/asm/loongarch.h */

"Based on kernel definitions: ..."

+
+/* Basic CSR register */
+#define LOONGARCH_CSR_CRMD   0x0 /* Current mode info */
Do we really need all these ad-hoc translated names when people could 
easily be pointed to the manuals? This way translation errors can be 
avoided, such as...

+FIELD(CSR_CRMD, PLV, 0, 2)
+FIELD(CSR_CRMD, IE, 2, 1)
+FIELD(CSR_CRMD, DA, 3, 1)
+FIELD(CSR_CRMD, PG, 4, 1)
+FIELD(CSR_CRMD, DATF, 5, 2)
+FIELD(CSR_CRMD, DATM, 7, 2)
+FIELD(CSR_CRMD, WE, 9, 1)
+
+#define LOONGARCH_CSR_PRMD   0x1 /* Prev-exception mode info */
+FIELD(CSR_PRMD, PPLV, 0, 2)
+FIELD(CSR_PRMD, PIE, 2, 1)
+FIELD(CSR_PRMD, PWE, 3, 1)
+
+#define LOONGARCH_CSR_EUEN   0x2 /* Extended unit enable */
+FIELD(CSR_EUEN, FPE, 0, 1)
+FIELD(CSR_EUEN, SXE, 1, 1)
+FIELD(CSR_EUEN, ASXE, 2, 1)
+FIELD(CSR_EUEN, BTE, 3, 1)
+
+#define LOONGARCH_CSR_MISC   0x3 /* Misc config */
+
+#define LOONGARCH_CSR_ECFG   0x4 /* Exception config */
+FIELD(CSR_ECFG, LIE, 0, 13)
+FIELD(CSR_ECFG, VS, 16, 3)
+
+#define LOONGARCH_CSR_ESTAT  0x5 /* Exception status */
+FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, ECODE, 16, 6)
+FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
+
+#define  EXCCODE_EXTERNAL_INT   64   /* plus external interrupt number */

what's "plus external interrupt"?

+#define  EXCCODE_INT 0
+#define  EXCCODE_PIL 1
+#define  EXCCODE_PIS 2
+#define  EXCCODE_PIF 3
+#define  EXCCODE_PME 4
+#define  EXCCODE_PNR 5
+#define  EXCCODE_PNX 6
+#define  EXCCODE_PPI 7
+#define  EXCCODE_ADEF8 /* Have different expsubcode */

"different exception subcodes"

+#define  EXCCODE_ADEM8 /* Have different expsubcode */
+#define  EXCCODE_ALE 9
+#define  EXCCODE_BCE 10
+#define  EXCCODE_SYS 11
+#define  EXCCODE_BRK 12
+#define  EXCCODE_INE 13
+#define  EXCCODE_IPE 14
+#define  EXCCODE_FPD 15
+#define  EXCCODE_SXD 16
+#define  EXCCODE_ASXD17
+#define  EXCCODE_FPE 18 /* Have different expsubcode */
+#define  EXCCODE_VFPE18
+#define  EXCCODE_WPEF19 /* Have different expsubcode */
+#define  EXCCODE_WPEM19
+#define  EXCCODE_BTD 20
+#define  EXCCODE_BTE 21
+#define  EXCCODE_DBP 26 /* Reserved decode used for debug */

"decode"? also "used for debugging"?

+
+#define LOONGARCH_CSR_ERA0x6 /* Exception return address */
+
+#define LOONGARCH_CSR_BADV   0x7 /* Bad virtual address */
+
+#define LOONGARCH_CSR_BADI   0x8 /* Bad instruction */
+
+#define LOONGARCH_CSR_EENTRY 0xc /* Exception enter base address */

"exception entrypoint"?

+
+/* TLB related CSR register */

"CSR register" is duplication; "R" is already "register". Also "CSRs"...

+#define LOONGARCH_CSR_TLBIDX 0x10 /* TLB Index, EHINV, PageSize, NP */
+FIELD(CSR_TLBIDX, INDEX, 0, 12)
+FIELD(CSR_TLBIDX, PS, 24, 6)
+FIELD(CSR_TLBIDX, NE, 31, 1)
+
+#define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi without ASID */

I cannot find the "without ASID" part in the Chinese manual...

+FIELD(CSR_TLBEHI, VPPN, 13, 35)
+
+#define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
+#define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
+FIELD(TLBENTRY, V, 0, 1)
+FIELD(TLBENTRY, D, 1, 1)
+FIELD(TLBENTRY, PLV, 2, 2)
+FIELD(TLBENTRY, MAT, 4, 2)
+FIELD(TLBENTRY, G, 6, 1)
+FIELD(TLBENTRY, PPN, 12, 36)
+FIELD(TLBENTRY, NR, 61, 1)
+FIELD(TLBENTRY, NX, 62, 1)
+FIELD(TLBENTRY, RPLV, 63, 1)
+
+#define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
+FIELD(CSR_ASID, ASID, 0, 10)
+FIELD(CSR_ASID, ASIDBITS, 16, 8)
+
+/* Page table base address when badv[47] = 0 */
+#define LOONGARCH_CSR_PGDL   0x19
+/* Page table base address when 

Re: [RFC PATCH v4 10/30] target/loongarch: Add other core instructions support

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

This includes:
-CACOP
-LDDIR
-LDPTE
-ERTN
-DBCL
-IDLE
Okay, now I got that the word "core" actually meant "privileged"... so 
please adjust all occurrences of that word.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/cpu.h   |  2 +
  target/loongarch/disas.c | 17 
  target/loongarch/helper.h|  4 +
  target/loongarch/insn_trans/trans_core.c.inc | 74 +
  target/loongarch/insns.decode| 11 +++
  target/loongarch/internals.h |  5 ++
  target/loongarch/op_helper.c | 43 ++
  target/loongarch/tlb_helper.c| 87 
  8 files changed, 243 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ddb69ffecf..2d5bae1af4 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -442,6 +442,8 @@ enum {
  EXCP_LAST = EXCP_FPE,
  };
  
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0

+
  #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
  #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
  #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 483270f331..516866c2d3 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -226,6 +226,17 @@ static void output_i_rr(DisasContext *ctx, arg_i_rr *a, 
const char *mnemonic)
  output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
  }
  
+static void output_cop_r_i(DisasContext *ctx, arg_cop_r_i *a,

+   const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->cop, a->rj, a->imm);
+}
+
+static void output_j_i(DisasContext *ctx, arg_j_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rj, a->imm);
+}
+
  #define INSN(insn, type)\
  static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
  {   \
@@ -556,6 +567,12 @@ INSN(tlbfill,  empty)
  INSN(tlbclr,   empty)
  INSN(tlbflush, empty)
  INSN(invtlb,   i_rr)
+INSN(cacop,cop_r_i)
"cop" reads like "co-processor" while you may just mean "cache op"... as 
the format is for this particular instruction only, you may as well just 
name the format "cacop" and be done with it. (AFAIK it's called "cache" 
before being renamed, allegedly for avoiding the MIPS name, but the new 
name is miserable and unpronounceable, coming up with names is hard but 
people should really try harder...)

+INSN(lddir,rr_i)
+INSN(ldpte,j_i)
+INSN(ertn, empty)
+INSN(idle, i)
+INSN(dbcl, i)
  
  #define output_fcmp(C, PREFIX, SUFFIX) \

  { 
 \
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 97af7ac8aa..c916f2650b 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -112,4 +112,8 @@ DEF_HELPER_2(invtlb_all_g, void, env, i32)
  DEF_HELPER_2(invtlb_all_asid, void, env, tl)
  DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
  DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
+DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
+DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
+DEF_HELPER_1(ertn, void, env)
+DEF_HELPER_1(idle, void, env)
  #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 5a8e9e0643..834ffc03d5 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -35,6 +35,12 @@ GEN_FALSE_TRANS(tlbfill)
  GEN_FALSE_TRANS(tlbclr)
  GEN_FALSE_TRANS(tlbflush)
  GEN_FALSE_TRANS(invtlb)
+GEN_FALSE_TRANS(cacop)
+GEN_FALSE_TRANS(ldpte)
+GEN_FALSE_TRANS(lddir)
+GEN_FALSE_TRANS(ertn)
+GEN_FALSE_TRANS(dbcl)
+GEN_FALSE_TRANS(idle)
  
  #else
  
@@ -335,4 +341,72 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)

  return true;
  }
  
+static bool trans_cacop(DisasContext *ctx, arg_cacop *a)

+{
+/* Treat the cacop as a nop */
+if (check_plv(ctx)) {
+return false;
+}
+return true;
+}
+
+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_ldpte(cpu_env, src1, tcg_constant_tl(a->imm), mem_idx);
+return true;
+}
+
+static bool trans_lddir(DisasContext *ctx, arg_lddir *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_lddir(dest, cpu_env, src, tcg_constant_tl(a->imm), 

Re: [PATCH v14 25/26] target/loongarch: 'make check-tcg' support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
Acked-by: Alex Bennée
Reviewed-by: Philippe Mathieu-Daudé
---
  tests/tcg/configure.sh | 1 +
  1 file changed, 1 insertion(+)

diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index 8eb4287c84..c3d7e45524 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -51,6 +51,7 @@ fi
  : ${cross_cc_cflags_armeb="-mbig-endian"}
  : ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"}
  : ${cross_cc_cflags_hexagon="-mv67 -O2 -static"}
+: ${cross_cc_loongarch64="loongarch64-unknown-linux-gnu-gcc"}
  : ${cross_cc_hppa="hppa-linux-gnu-gcc"}
  : ${cross_cc_i386="i686-linux-gnu-gcc"}
  : ${cross_cc_cflags_i386="-m32"}

Reviewed-by: WANG Xuerui 



Re: [PATCH v14 24/26] target/loongarch: Add target build suport

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds build loongarch-linux-user target support.


Chinglish... You may just say "target: Add the loongarch target_arch" 
and remove this sentence.



Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé
---
  target/loongarch/meson.build | 19 +++
  target/meson.build   |  1 +
  2 files changed, 20 insertions(+)
  create mode 100644 target/loongarch/meson.build

diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
new file mode 100644
index 00..bcb076e55f
--- /dev/null
+++ b/target/loongarch/meson.build
@@ -0,0 +1,19 @@
+gen = decodetree.process('insns.decode')
+
+loongarch_ss = ss.source_set()
+loongarch_ss.add(files(
+  'cpu.c',
+  'disas.c',
+))
+loongarch_tcg_ss = ss.source_set()
+loongarch_tcg_ss.add(gen)
+loongarch_tcg_ss.add(files(
+  'fpu_helper.c',
+  'op_helper.c',
+  'translate.c',
+))
+loongarch_tcg_ss.add(zlib)
+
+loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
+
+target_arch += {'loongarch': loongarch_ss}
diff --git a/target/meson.build b/target/meson.build
index 2f6940255e..a53a60486f 100644
--- a/target/meson.build
+++ b/target/meson.build
@@ -5,6 +5,7 @@ subdir('cris')
  subdir('hexagon')
  subdir('hppa')
  subdir('i386')
+subdir('loongarch')
  subdir('m68k')
  subdir('microblaze')
  subdir('mips')




Re: [RFC PATCH v4 12/30] target/loongarch: Add timer related instructions support.

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:14, Xiaojuan Yang wrote:

This includes:
-RDTIME{L/H}.W
-RDTIME.D

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/helper.h |  1 +
  target/loongarch/insn_trans/trans_extra.c.inc | 32 +++
  target/loongarch/op_helper.c  |  6 
  target/loongarch/translate.c  |  2 ++
  4 files changed, 41 insertions(+)

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index c916f2650b..035bd141ed 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -116,4 +116,5 @@ DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
  DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
  DEF_HELPER_1(ertn, void, env)
  DEF_HELPER_1(idle, void, env)
+DEF_HELPER_1(rdtime_d, i64, env)

Are we missing rdtimel_w and rdtimeh_w here?

  #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc 
b/target/loongarch/insn_trans/trans_extra.c.inc
index 2ce95d3382..8d3425ba61 100644
--- a/target/loongarch/insn_trans/trans_extra.c.inc
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
@@ -33,22 +33,54 @@ static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d 
* a)
  return true;
  }
  
+#ifndef CONFIG_USER_ONLY

+static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
+   bool word, bool high)
+{
+TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_rdtime_d(dst1, cpu_env);
+if (word) {
+tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
+}
+tcg_gen_ld_i64(dst2, cpu_env, offsetof(CPULoongArchState, CSR_TID));
+
+return true;
+}
+#endif
+
  static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a)
  {
+#ifdef CONFIG_USER_ONLY
  tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
  return true;
+#else
+return gen_rdtime(ctx, a, 1, 0);
+#endif
  }
  
  static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)

  {
+#ifdef CONFIG_USER_ONLY
  tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
  return true;
+#else
+return gen_rdtime(ctx, a, 1, 1);
+#endif
  }
  
  static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)

  {
+#ifdef CONFIG_USER_ONLY
  tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
  return true;
+#else
+return gen_rdtime(ctx, a, 0, 0);
+#endif
  }
  
  static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)

diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index 6f9742054a..1d8b501ab9 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -133,4 +133,10 @@ void helper_idle(CPULoongArchState *env)
   */
  do_raise_exception(env, EXCP_HLT, 0);
  }
+
+uint64_t helper_rdtime_d(CPULoongArchState *env)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(env_cpu(env));
+ return cpu_loongarch_get_constant_timer_counter(cpu);
+}
  #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index ddb97661fa..53a5ef3aa9 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -25,6 +25,8 @@ static TCGv cpu_lladdr, cpu_llval;
  TCGv_i32 cpu_fcsr0;
  TCGv_i64 cpu_fpr[32];
  
+#include "exec/gen-icount.h"

+
  #define DISAS_STOP   DISAS_TARGET_0
  #define DISAS_EXIT   DISAS_TARGET_1
  




Re: [PATCH v14 21/26] linux-user: Add LoongArch syscall support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

We should disable '__BITS_PER_LONG' at [1] before run gensyscalls.sh

  [1] arch/loongarch/include/uapi/asm/bitsperlong.h

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé
---
  linux-user/loongarch64/syscall_nr.h | 313 
  linux-user/loongarch64/target_syscall.h |  48 
  linux-user/syscall_defs.h   |  10 +-
  scripts/gensyscalls.sh  |   1 +
  4 files changed, 368 insertions(+), 4 deletions(-)
  create mode 100644 linux-user/loongarch64/syscall_nr.h
  create mode 100644 linux-user/loongarch64/target_syscall.h


This is exactly what we don't want to merge before the Linux port (and 
glibc) lands; things like UNAME_MINIMUM_RELEASE and the syscall numbers 
certainly need to be updated afterwards. Otherwise everything looks good 
though.


The "struct { ... } csr" part suggested by Philippe is deviating from 
the kernel sources, but the memory layout is the same, and in looking at 
other targets it seems we're not required to keep exact correspondence 
with kernel -- am I right? (Many targets do use the exact definition as 
kernel, e.g. aarch64, though)





Re: [RFC PATCH v4 01/30] target/loongarch: Update README

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:13, Xiaojuan Yang wrote:

Mainly introduce how to run the softmmu
This sentence serves little purpose and is broken English, so it is 
better removed.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  target/loongarch/README | 25 +
  1 file changed, 25 insertions(+)

diff --git a/target/loongarch/README b/target/loongarch/README
index d5780c5918..337ba55f33 100644
--- a/target/loongarch/README
+++ b/target/loongarch/README
@@ -72,6 +72,31 @@
./qemu-loongarch64  /opt/clfs/usr/bin/pwd
...
  
+- Softmmu emulation

You may mean "System emulation" instead?

+
+  Add support softmmu emulation support in the following series patches.
People don't care about patch series when they look at this file after 
everything is merged; they are NOT looking at Patchew or mailing lists 
when browsing code either locally or on GitLab/GitHub. You may just drop 
this sentence.

+  Mainly emulate a virt 3A5000 board and ls7a bridge that is not exactly
+  the same as the host. Kernel code and uefi code is on the github.

So what exactly is the difference? And does it affect general use?

+  All required binaries can get from github for test.
English problem; "You can get all required binaries from GitHub for 
testing."

+
+  1.Download kernel and the cross-tools.(vmlinux)
+
+https://github.com/loongson/linux/tree/loongarch-next
+https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz
+
+  2.Download uefi code.(loongarch_bios.bin)
+
+https://github.com/loongson/edk2/tree/LoongArch
+https://github.com/loongson/edk2-platforms
+
+  3.Download the clfs-system and make a ramdisk with busybox.(ramdisk)
How do we make the ramdisk, or is it prebuilt too? It's not clear from 
the description.

+
+  4.Run with command,eg:
+
+   ./build/qemu-system-loongarch64 -m 4G -smp 4 --cpu Loongson-3A5000 --machine 
loongson3-ls7a -kernel ./vmlinux -initrd ./ramdisk  -append "root=/dev/ram 
console=ttyS0,115200 rdinit=/sbin/init loglevel=8" -monitor tcp::4000,server,nowait 
-nographic
+
+The vmlinux, ramdisk and uefi binary loongarch_bios.bin can get from :

Broken English too.

+git clonehttps://github.com/yangxiaojuan-loongson/qemu-binary
  
  - Note.

We can get the latest LoongArch documents or LoongArch tools 
athttps://github.com/loongson/


Overall the English is so badly written that I cannot easily comprehend 
some of the sentences, even as a native Chinese speaker, familiar with 
common Chinglish patterns.


I suggest just rewriting the whole thing, possibly with help from 
someone else more familiar with technical English in your company. You'd 
want to check your other usages of English throughout the series, too.





Re: [PATCH v14 19/26] linux-user: Add LoongArch signal support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
---
  linux-user/loongarch64/signal.c| 198 +
  linux-user/loongarch64/target_signal.h |  13 ++
  2 files changed, 211 insertions(+)
  create mode 100644 linux-user/loongarch64/signal.c
  create mode 100644 linux-user/loongarch64/target_signal.h

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
new file mode 100644
index 00..9f0e6421b2
--- /dev/null
+++ b/linux-user/loongarch64/signal.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation of Linux signals
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "signal-common.h"
+#include "user-internals.h"
+#include "linux-user/trace.h"
+
+#define FPU_REG_WIDTH 256
+union fpureg {
+uint32_t val32[FPU_REG_WIDTH / 32];
+uint64_t val64[FPU_REG_WIDTH / 64];
+};
This is code preemptively added to support the LASX extensions? I 
remember the LASX extension in 3A4000/MIPS era uses 256-bit vector 
registers just like this.

+
+struct target_sigcontext {
+uint64_t sc_pc;
+uint64_t sc_regs[32];
+uint32_t sc_flags;
+uint32_t sc_fcsr;
+uint32_t sc_vcsr;
+uint64_t sc_fcc;
+uint64_t sc_scr[4];
+union fpureg sc_fpregs[32] __attribute__((aligned(32)));
+uint8_t sc_reserved[4096] __attribute__((aligned(16)));
+};
As Richard pointed out, you need to have this synchronized to the 
kernel's definition. It's okay to update after SIMD support lands there, 
it's not to be considered code churn.

+
+struct target_ucontext {
+target_ulong tuc_flags;
+struct target_ucontext *tuc_link;
+target_stack_t tuc_stack;
+target_sigset_t tuc_sigmask;
+uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
+struct target_sigcontext tuc_mcontext;
+};
+
+struct target_rt_sigframe {
+struct target_siginfo rs_info;
+struct target_ucontext rs_uc;
+};
+
+static uint64_t read_all_fcc(CPULoongArchState *env)
+{
+uint64_t ret = 0;
+
+for (int i = 0; i < 8; ++i) {
+ret |= (uint64_t)env->cf[i] << (i * 8);
+}
+
+return ret;
+}
+
+static void write_all_fcc(CPULoongArchState *env, uint64_t val)
+{
+for (int i = 0; i < 8; ++i) {
+env->cf[i] = (val >> (i * 8)) & 1;
+}
+}
+
+static inline void setup_sigcontext(CPULoongArchState *env,
+struct target_sigcontext *sc)
+{
+int i;
+
+__put_user(env->pc, >sc_pc);
+__put_user(0, >sc_regs[0]);
+__put_user(env->fcsr0, >sc_fcsr);
+__put_user(0, >sc_vcsr);
+sc->sc_fcc = read_all_fcc(env);
+
+for (i = 0; i < 4; ++i) {
+__put_user(0, >sc_scr[i]);
+}
+
+for (i = 1; i < 32; ++i) {
+__put_user(env->gpr[i], >sc_regs[i]);
+}
+
+for (i = 0; i < 32; ++i) {
+__put_user(env->fpr[i], >sc_fpregs[i].val64[0]);
+}
+}
+
+static inline void
+restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc)
+{
+int i;
+
+__get_user(env->pc, >sc_pc);
+__get_user(env->fcsr0, >sc_fcsr);
+write_all_fcc(env, sc->sc_fcc);
+
+for (i = 1; i < 32; ++i) {
+__get_user(env->gpr[i], >sc_regs[i]);
+}
+
+for (i = 0; i < 32; ++i) {
+__get_user(env->fpr[i], >sc_fpregs[i].val64[0]);
+}
+}
+
+/*
+ * Determine which stack to use..

Duplicate period (".").

+ */
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPULoongArchState *env,
+ size_t frame_size)
+{
+unsigned long sp;
+
+sp = target_sigsp(get_sp_from_cpustate(env) - 32, ka);
+
+return (sp - frame_size) & ~15;
+}
+
+void setup_rt_frame(int sig, struct target_sigaction *ka,
+target_siginfo_t *info,
+target_sigset_t *set, CPULoongArchState *env)
+{
+struct target_rt_sigframe *frame;
+abi_ulong frame_addr;
+int i;
+
+frame_addr = get_sigframe(ka, env, sizeof(*frame));
+trace_user_setup_rt_frame(env, frame_addr);
+if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+goto give_sigsegv;
+}
+
+tswap_siginfo(>rs_info, info);
+
+__put_user(0, >rs_uc.tuc_flags);
+__put_user(0, >rs_uc.tuc_link);
+target_save_altstack(>rs_uc.tuc_stack, env);
+
+setup_sigcontext(env, >rs_uc.tuc_mcontext);
+
+for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+__put_user(set->sig[i], >rs_uc.tuc_sigmask.sig[i]);
+}
+
+env->gpr[4] = sig;
+env->gpr[5] = frame_addr + offsetof(struct target_rt_sigframe, rs_info);
+env->gpr[6] = frame_addr + offsetof(struct target_rt_sigframe, rs_uc);
+env->gpr[3] = frame_addr;
+env->gpr[1] = default_rt_sigreturn;
+
+env->pc = ka->_sa_handler;
+unlock_user_struct(frame, frame_addr, 1);
+return;
+
+give_sigsegv:
+unlock_user_struct(frame, frame_addr, 1);
+force_sigsegv(sig);
+}
+
+long do_rt_sigreturn(CPULoongArchState 

Re: [RFC PATCH v4 11/30] target/loongarch: Add LoongArch interrupt and exception handle

2022-01-09 Thread WANG Xuerui



On 1/8/22 17:14, Xiaojuan Yang wrote:

1.This patch Add loongarch interrupt and exception handle.
2.Rename the user excp to the exccode from the csr defintions.

Signed-off-by: Xiaojuan Yang
Signed-off-by: Song Gao
---
  linux-user/loongarch64/cpu_loop.c |   8 +-
  target/loongarch/cpu.c| 252 +-
  target/loongarch/cpu.h|  11 -
  target/loongarch/fpu_helper.c |   2 +-
  target/loongarch/insn_trans/trans_extra.c.inc |   4 +-
  target/loongarch/translate.c  |   2 +-
  6 files changed, 254 insertions(+), 25 deletions(-)

diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
index 6628d215ca..dd58eb048f 100644
--- a/linux-user/loongarch64/cpu_loop.c
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -28,7 +28,7 @@ void cpu_loop(CPULoongArchState *env)
  case EXCP_INTERRUPT:
  /* just indicate that signals should be handled asap */
  break;
-case EXCP_SYSCALL:
+case EXCCODE_SYS:
  env->pc += 4;
  ret = do_syscall(env, env->gpr[11],
   env->gpr[4], env->gpr[5],
@@ -48,10 +48,10 @@ void cpu_loop(CPULoongArchState *env)
  }
  env->gpr[4] = ret;
  break;
-case EXCP_INE:
+case EXCCODE_INE:
  force_sig_fault(TARGET_SIGILL, 0, env->pc);
  break;
-case EXCP_FPE:
+case EXCCODE_FPE:
  si_code = TARGET_FPE_FLTUNK;
  if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
  si_code = TARGET_FPE_FLTINV;
@@ -67,7 +67,7 @@ void cpu_loop(CPULoongArchState *env)
  force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
  break;
  case EXCP_DEBUG:
-case EXCP_BREAK:
+case EXCCODE_BRK:
  force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
  break;
  case EXCP_ATOMIC:
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 571092ce53..caab59b83a 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -30,11 +30,23 @@ const char * const fregnames[32] = {
  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
  };
  
-static const char * const excp_names[EXCP_LAST + 1] = {

-[EXCP_SYSCALL] = "Syscall",
-[EXCP_BREAK] = "Break",
-[EXCP_INE] = "Instruction Non-existent",
-[EXCP_FPE] = "Floating Point Exception",
+static const char * const excp_names[] = {
+[EXCCODE_INT] = "Interrupt",
+[EXCCODE_PIL] = "TLB load page invalid",
+[EXCCODE_PIS] = "TLB store page invalid",
+[EXCCODE_PIF] = "TLB Fetch page invalid",
Where do the translations come from? According to the Chinese original, 
we should have "Page Invalid for {Load,Store,instruction Fetch}" here 
for correct acronyms.

+[EXCCODE_PME] = "TLB Page modify",
+[EXCCODE_PNR] = "TLB read-inhibit",
+[EXCCODE_PNX] = "TLB execute-inhibit",
+[EXCCODE_PPI] = "TLB priviledged error",
And "Page Modified Exception", "Page Not Readable", "Page Not 
Executable", and "Page Privilege Error" accordingly.

+[EXCCODE_ADEF] = "Fetch instruction error",
+[EXCCODE_ADEM] = "Memory access error",
And "Address Error for instruction Fetch", and "Address Error for Memory 
access".

+[EXCCODE_SYS] = "Syscall",
+[EXCCODE_BRK] = "Break",
+[EXCCODE_INE] = "Instruction Non-existent",
+[EXCCODE_IPE] = "Instruction priveiledged error",

"Instruction Privilege Error"

+[EXCCODE_FPE] = "Floating Point Exception",
+[EXCCODE_DBP] = "Debug breakpoint",
If you re-organize the series so that basic CPU emulation and system 
emulation come first, you may want to squash part of this commit into 
the former commit defining this array.

  };
  
  const char *loongarch_exception_name(int32_t exception)

@@ -66,6 +78,215 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
  env->pc = value;
  }
  
+#if !defined(CONFIG_USER_ONLY)

+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env)
+{
+bool ret = 0;
+
+ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) &&
+  !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)));
+
+return ret;
+}
+
+/* Check if there is pending and not masked out interrupt */
+static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
+{
+uint32_t pending;
+uint32_t status;
+bool r;
+
+pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS);
+status  = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE);
+
+r = (pending & status) != 0;
+return r;
+}
+
+static inline unsigned int get_vint_size(CPULoongArchState *env)
+{
+uint64_t vs = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
+uint64_t size = 0;
+
+if (vs == 0) {
+return 0;
+}
+
+if (vs < 8) {
+size = 1 << (vs + 2);
+}
+
+if (vs > 8) {
+qemu_log("%s: unexpected value", __func__);
+assert(0);
+ 

Re: [PATCH v14 23/26] default-configs: Add loongarch linux-user support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds loongarch64 linux-user default configs file.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  configs/targets/loongarch64-linux-user.mak | 3 +++
  1 file changed, 3 insertions(+)
  create mode 100644 configs/targets/loongarch64-linux-user.mak

diff --git a/configs/targets/loongarch64-linux-user.mak 
b/configs/targets/loongarch64-linux-user.mak
new file mode 100644
index 00..5b0acfa3ec
--- /dev/null
+++ b/configs/targets/loongarch64-linux-user.mak
@@ -0,0 +1,3 @@
+# Default configuration for loongson64-linux-user

"loongarch64-linux-user"?

+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch


With that fixed:

Reviewed-by: WANG Xuerui 




Re: [PATCH v14 01/26] target/loongarch: Add README

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch gives an introduction to the LoongArch target.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  MAINTAINERS |  5 +++
  target/loongarch/README | 77 +
  2 files changed, 82 insertions(+)
  create mode 100644 target/loongarch/README

diff --git a/MAINTAINERS b/MAINTAINERS
index f871d759fd..2df0d4a7c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -213,6 +213,11 @@ S: Maintained
  F: target/hppa/
  F: disas/hppa.c
  
+LoongArch TCG CPUS

"TCG CPUs" -- notice the case for the plural "s".

+M: Song Gao
+S: Maintained
+F: target/loongarch/
+
  M68K TCG CPUs
  M: Laurent Vivier
  S: Maintained
diff --git a/target/loongarch/README b/target/loongarch/README
new file mode 100644
index 00..d5780c5918
--- /dev/null
+++ b/target/loongarch/README
@@ -0,0 +1,77 @@
+- Introduction
+
+  LoongArch is the general processor architecture of Loongson.
+
+  The following versions of the LoongArch core are supported
+core: 3A5000
+https://github.com/loongson/LoongArch-Documentation/releases/download/2021.08.17/LoongArch-Vol1-v1.00-EN.pdf
+
+  We can get the latest loongarch documents 
athttps://github.com/loongson/LoongArch-Documentation/tags.
+
+
+- Linux-user emulation
+
+  We already support Linux user emulation. We can use LoongArch cross-tools to 
build LoongArch executables on X86 machines,
+  and We can also use qemu-loongarch64 to run LoongArch executables.
+
+  1. Install LoongArch cross-tools on X86 machines.
+
+Download cross-tools.
+
+  
wgethttps://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz
+
+  tar -vxf loongarch64-clfs-20211202-cross-tools.tar.xz -C /opt
+
+Config cross-tools env.
+
+  . setenv.sh
+
+  setenv.sh:
+
+  #!/bin/sh
+  set -x
+  CC_PREFIX=/opt/cross-tools
+
+  export PATH=$CC_PREFIX/bin:$PATH
+  export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH
+  export 
LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
+  set +x
+
+  2. Test tests/tcg/multiarch.
+
+./configure --disable-rdma --disable-pvrdma --prefix=/usr  \
+--target-list="loongarch64-linux-user"  \
+--disable-libiscsi --disable-libnfs --disable-libpmem \
+--disable-glusterfs --enable-libusb --enable-usb-redir \
+--disable-opengl --disable-xen --enable-spice --disable-werror \
+--enable-debug --disable-capstone --disable-kvm --enable-profiler
+
+cd  build/
+
+make && make check-tcg
+
+  3. Run LoongArch system basic command with loongarch-clfs-system.
+
+Download clfs-system.
+
+  
wgethttps://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-12-02.tar.bz2
+
+  tar -vxf loongarch64-clfs-system-2021-12-02.tar.bz2 -C /opt/clfs
+  ln -s /opt/clfs/  /opt/clfs/tls
Command with dubious intention -- are you working around some kind of 
LIBPATH priority problem? TLS shouldn't be involved at this level, yet I 
remotely remember that library search paths similar to "/usr/lib/tls" 
were a thing long ago...

+
+Config env.
+
+  cp /opt/clfs/lib64/ld-linux-loongarch64.so.1   /lib64
+
+  export LD_LIBRARY_PATH="/opt/clfs/lib64"
+
+Run LoongArch system basic command.
+
+  ./qemu-loongarch64  /opt/clfs/usr/bin/bash
+  ./qemu-loongarch64  /opt/clfs/usr/bin/ls
+  ./qemu-loongarch64  /opt/clfs/usr/bin/pwd
+  ...
+
+
+- Note.
+  We can get the latest LoongArch documents or LoongArch tools 
athttps://github.com/loongson/
I'm afraid this README would require some re-writing due to the amount 
of Chinglish involved, but that's possibly okay after merging. (I don't 
have the time to rewrite this for you currently, so just a mild rant for 
now.)




Re: [PATCH v14 22/26] linux-user: Add LoongArch cpu_loop support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  configure   |  3 +
  linux-user/loongarch64/cpu_loop.c   | 94 +
  linux-user/loongarch64/target_cpu.h | 34 +++
  3 files changed, 131 insertions(+)
  create mode 100644 linux-user/loongarch64/cpu_loop.c
  create mode 100644 linux-user/loongarch64/target_cpu.h

diff --git a/configure b/configure
index 030728d11e..93c4e5bd92 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,9 @@ case "$cpu" in
mips*)
  cpu="mips" ;;
  
+  loongarch)

+cpu="loongarch64" ;;
+
Do you really need this? Looking at the part above setting initial value 
for $cpu, you can only get here if $cpu is given on command-line, or 
returned by uname on a presumably LoongArch system not defining 
__loongarch64. Either would be unlikely though, and we really don't want 
to turn on 64-bit code for 32-bit hosts (that don't exist at the 
moment), so this case seems useless.

ppc)
  CPU_CFLAGS="-m32" ;;
ppc64)
diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
new file mode 100644
index 00..6628d215ca
--- /dev/null
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch user cpu_loop.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "qemu-common.h"
+#include "user-internals.h"
+#include "cpu_loop-common.h"
+#include "signal-common.h"
+
+void cpu_loop(CPULoongArchState *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr, si_code;
+abi_long ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_SYSCALL:
+env->pc += 4;
+ret = do_syscall(env, env->gpr[11],
+ env->gpr[4], env->gpr[5],
+ env->gpr[6], env->gpr[7],
+ env->gpr[8], env->gpr[9],
+ -1, -1);
+if (ret == -QEMU_ERESTARTSYS) {
+env->pc -= 4;
+break;
+}
+if (ret == -QEMU_ESIGRETURN) {
+/*
+ * Returning from a successful sigreturn syscall.
+ * Avoid clobbering register state.
+ */
+break;
+}
+env->gpr[4] = ret;
+break;
+case EXCP_INE:
+force_sig_fault(TARGET_SIGILL, 0, env->pc);
+break;
+case EXCP_FPE:
+si_code = TARGET_FPE_FLTUNK;
+if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
+si_code = TARGET_FPE_FLTINV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
+si_code = TARGET_FPE_FLTDIV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
+si_code = TARGET_FPE_FLTOVF;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
+si_code = TARGET_FPE_FLTUND;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
+si_code = TARGET_FPE_FLTRES;
+}
+force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
+break;
+case EXCP_DEBUG:
+case EXCP_BREAK:
+force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
+  trapnr);
+exit(EXIT_FAILURE);
+}
+process_pending_signals(env);
+}
+}
+
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+env->gpr[i] = regs->regs[i];
+}
+env->pc = regs->csr.era;
+
+}
diff --git a/linux-user/loongarch64/target_cpu.h 
b/linux-user/loongarch64/target_cpu.h
new file mode 100644
index 00..a29af66156
--- /dev/null
+++ b/linux-user/loongarch64/target_cpu.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_CPU_H
+#define LOONGARCH_TARGET_CPU_H
+
+static inline void cpu_clone_regs_child(CPULoongArchState *env,
+target_ulong newsp, unsigned flags)
+{
+if (newsp) {
+env->gpr[3] = newsp;
+}
+env->gpr[4] = 0;
+}
+
+static inline void cpu_clone_regs_parent(CPULoongArchState *env,
+   

Re: [PATCH v14 20/26] linux-user: Add LoongArch elf support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé
---
  linux-user/elfload.c| 53 +
  linux-user/loongarch64/target_elf.h | 12 +++
  2 files changed, 65 insertions(+)
  create mode 100644 linux-user/loongarch64/target_elf.h

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 767f54c76d..2ee83778f2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -914,6 +914,59 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, 
const CPUPPCState *en
  
  #endif
  
+#ifdef TARGET_LOONGARCH64

+
+#define ELF_START_MMAP 0x8000
+
+#define ELF_CLASS   ELFCLASS64
+#define ELF_ARCHEM_LOONGARCH
+
+#define elf_check_arch(x) ((x) == EM_LOONGARCH)
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->csr.crmd = 2 << 3;
This is just "1 << 4" and means to set the CSR.CRMD.PG bit, indicating 
that page translation is enabled; it's better to explain this somehow. 
(In writing this comment I realized you might be saying "0b10 << 3" 
instead, because the only valid combinations for the DA and PG bits are 
0b01 and 0b10; so "0b10 << 3" is also okay and maybe clearer.)

+regs->csr.era = infop->entry;
+regs->regs[3] = infop->start_stack;
+}
+
+/* See linux kernel: arch/loongarch/include/asm/elf.h.  */
+#define ELF_NREG 45
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+enum {
+TARGET_EF_R0 = 0,
+TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32,
+TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33,
+};
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+   const CPULoongArchState *env)
+{
+int i;
+
+(*regs)[TARGET_EF_R0] = 0;
+
+for (i = 1; i < ARRAY_SIZE(env->gpr); i++) {
+(*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]);
+}
+
+(*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
+(*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->badaddr);
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE4096
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+return 0;
+}
+
+#endif /* TARGET_LOONGARCH64 */
+
  #ifdef TARGET_MIPS
  
  #define ELF_START_MMAP 0x8000

diff --git a/linux-user/loongarch64/target_elf.h 
b/linux-user/loongarch64/target_elf.h
new file mode 100644
index 00..3c690bbf5b
--- /dev/null
+++ b/linux-user/loongarch64/target_elf.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_ELF_H
+#define LOONGARCH_TARGET_ELF_H
+static inline const char *cpu_get_model(uint32_t eflags)
+{
+return "Loongson-3A5000";
+}
+#endif




Re: [PATCH v14 26/26] scripts: add loongarch64 binfmt config

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:42, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  scripts/qemu-binfmt-conf.sh | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 7de996d536..da6a937be8 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -4,7 +4,7 @@
  qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \
  ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \
  sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
-microblaze microblazeel or1k x86_64 hexagon"
+microblaze microblazeel or1k x86_64 hexagon loongarch64"
  
  i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'

  
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
@@ -140,6 +140,10 @@ 
hexagon_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
  
hexagon_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
  hexagon_family=hexagon
  
+loongarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01'

+loongarch64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+loongarch64_family=loongarch
+
  qemu_get_family() {
  cpu=${HOST_ARCH:-$(uname -m)}
  case "$cpu" in


We don't have code in qemu_get_family to recognize "loongarch*" from 
uname output as "loongarch" family (you can even understand it as I 
missed this change in my TCG port series...), but otherwise this looks OK.


I can add the host CPU family recognition myself; for this patch,

Reviewed-by: WANG Xuerui 




Re: [PATCH v14 16/26] target/loongarch: Add disassembler

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds support for disassembling via option '-d in_asm'.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  include/disas/dis-asm.h  |   2 +
  meson.build  |   1 +
  target/loongarch/disas.c | 612 +++
  3 files changed, 615 insertions(+)
  create mode 100644 target/loongarch/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 08e1beec85..aeab30f19c 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -253,6 +253,7 @@ enum bfd_architecture
  #define bfd_mach_rx0x75
  #define bfd_mach_rx_v2 0x76
  #define bfd_mach_rx_v3 0x77
+  bfd_arch_loongarch,
bfd_arch_last
};
  #define bfd_mach_s390_31 31
@@ -461,6 +462,7 @@ int print_insn_riscv32  (bfd_vma, 
disassemble_info*);
  int print_insn_riscv64  (bfd_vma, disassemble_info*);
  int print_insn_rx(bfd_vma, disassemble_info *);
  int print_insn_hexagon(bfd_vma, disassemble_info *);
+int print_insn_loongarch(bfd_vma, disassemble_info *);
  
  #ifdef CONFIG_CAPSTONE

  bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
diff --git a/meson.build b/meson.build
index 53065e96ec..fa4c6dd241 100644
--- a/meson.build
+++ b/meson.build
@@ -1848,6 +1848,7 @@ disassemblers = {
'sh4' : ['CONFIG_SH4_DIS'],
'sparc' : ['CONFIG_SPARC_DIS'],
'xtensa' : ['CONFIG_XTENSA_DIS'],
+  'loongarch' : ['CONFIG_LOONGARCH_DIS'],
  }
  if link_language == 'cpp'
disassemblers += {
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
new file mode 100644
index 00..45be34de27
--- /dev/null
+++ b/target/loongarch/disas.c
@@ -0,0 +1,612 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch Disassembler
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+
+typedef struct {
+disassemble_info *info;
+uint64_t pc;
+uint32_t insn;
+} DisasContext;
+
+static inline int plus_1(DisasContext *ctx, int x)
+{
+return x + 1;
+}
+
+static inline int shl_2(DisasContext *ctx, int x)
+{
+return x * 4;
Although "<< 2" has the same effect as "* 4" here, isn't "<< 2" better 
in matching the function name?

+}
+
+#define output(C, INSN, FMT, ...)   \
+{   \
+(C)->info->fprintf_func((C)->info->stream, "%08x   %-9s\t" FMT, \
+(C)->insn, INSN, ##__VA_ARGS__);\
+}
+
+#include "decode-insns.c.inc"
+
+int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
+{
+bfd_byte buffer[4];
+uint32_t insn;
+int status;
+
+status = (*info->read_memory_func)(memaddr, buffer, 4, info);
+if (status != 0) {
+(*info->memory_error_func)(status, memaddr, info);
+return -1;
+}
+insn = bfd_getl32(buffer);
+DisasContext ctx = {
+.info = info,
+.pc = memaddr,
+.insn = insn
+};
+
+if (!decode(, insn)) {
+output(, "illegal", "");
+}
+return 4;
+}
+
+static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
+}
+
+static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
+}
+
+static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
+}
+
+static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
+}
+
+static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
+}
+
+static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls);
+}
+
+static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
+const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
+}
+
+static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d", a->imm);
+}
+
+static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
+ const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
+}
+
+static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
+}
+
+static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
+}
+
+static void 

Re: [PATCH v14 03/26] target/loongarch: Add main translation routines

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds main translation routines and
basic functions for translation.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  target/loongarch/helper.h|   6 ++
  target/loongarch/op_helper.c |  21 +
  target/loongarch/translate.c | 159 +++
  target/loongarch/translate.h |  26 ++
  4 files changed, 212 insertions(+)
  create mode 100644 target/loongarch/helper.h
  create mode 100644 target/loongarch/op_helper.c
  create mode 100644 target/loongarch/translate.c
  create mode 100644 target/loongarch/translate.h

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
new file mode 100644
index 00..eb771c0628
--- /dev/null
+++ b/target/loongarch/helper.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
new file mode 100644
index 00..903810951e
--- /dev/null
+++ b/target/loongarch/op_helper.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "internals.h"
+
+/* Exceptions helpers */
+void helper_raise_exception(CPULoongArchState *env, uint32_t exception)
+{
+do_raise_exception(env, exception, GETPC());
+}
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
new file mode 100644
index 00..048c8953b6
--- /dev/null
+++ b/target/loongarch/translate.c
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation for QEMU - main translation routines.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg/tcg-op.h"
+#include "exec/translator.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+
+#include "exec/translator.h"
+#include "exec/log.h"
+#include "qemu/qemu-print.h"
+#include "translate.h"
+#include "internals.h"
+
+/* Global register indices */
+TCGv cpu_gpr[32], cpu_pc;
+static TCGv cpu_lladdr, cpu_llval;
+TCGv_i32 cpu_fcsr0;
+TCGv_i64 cpu_fpr[32];
+
+#define DISAS_STOP   DISAS_TARGET_0
+
+void generate_exception(DisasContext *ctx, int excp)
+{
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+{
+if (translator_use_goto_tb(>base, dest)) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_exit_tb(ctx->base.tb, n);
+} else {
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_lookup_and_goto_ptr();
+}
+}
+
+static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
+CPUState *cs)
+{
+int64_t bound;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
+ctx->mem_idx = ctx->base.tb->flags;
+
+/* Bound the number of insns to execute to those left on the page.  */
+bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
+ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
+}
+
+static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
+{
+}
+
+static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+tcg_gen_insn_start(ctx->base.pc_next);
+}
+
+static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+CPULoongArchState *env = cs->env_ptr;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+
+if (!decode(ctx, ctx->opcode)) {
+qemu_log_mask(LOG_UNIMP, "Error: unkown opcode. 0x%lx: 0x%x\n",

Typo: "unknown"

+  ctx->base.pc_next, ctx->opcode);
+generate_exception(ctx, EXCP_INE);
+}
+
+ctx->base.pc_next += 4;
+}
+
+static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+switch (ctx->base.is_jmp) {
+case DISAS_STOP:
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+tcg_gen_lookup_and_goto_ptr();
+break;
+case DISAS_TOO_MANY:
+gen_goto_tb(ctx, 0, ctx->base.pc_next);
+break;
+case DISAS_NORETURN:
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void 

Re: [PATCH v14 02/26] target/loongarch: Add core definition

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds target state header, target definitions
and initialization routines.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé
---
  target/loongarch/cpu-param.h |  18 ++
  target/loongarch/cpu.c   | 314 +++
  target/loongarch/cpu.h   | 252 
  target/loongarch/internals.h |  21 +++
  4 files changed, 605 insertions(+)
  create mode 100644 target/loongarch/cpu-param.h
  create mode 100644 target/loongarch/cpu.c
  create mode 100644 target/loongarch/cpu.h
  create mode 100644 target/loongarch/internals.h

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
new file mode 100644
index 00..9a769b67e0
--- /dev/null
+++ b/target/loongarch/cpu-param.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU parameters for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_PARAM_H
+#define LOONGARCH_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 64
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
+#define TARGET_VIRT_ADDR_SPACE_BITS 48
+
+#define TARGET_PAGE_BITS 14
Aren't we capable of page sizes up to 64KiB? Minimal feasible page size 
is indeed 16KiB though (due to cache aliasing, although 4KiB pages are 
supported in hardware, they don't work in practice).

+#define NB_MMU_MODES 4
+
+#endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
new file mode 100644
index 00..76b89d1606
--- /dev/null
+++ b/target/loongarch/cpu.c
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CPU
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "sysemu/qtest.h"
+#include "exec/exec-all.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu.h"
+#include "internals.h"
+#include "fpu/softfloat-helpers.h"
+
+const char * const regnames[32] = {
+"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+
+const char * const fregnames[32] = {
+"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+static const char * const excp_names[EXCP_LAST + 1] = {
+[EXCP_SYSCALL] = "Syscall",
+[EXCP_BREAK] = "Break",
+[EXCP_INE] = "Instruction Non-existent",
Nit: "Instruction Non-Existent" (or is there any authoritative source 
for this spelling? the English translation of the manual?)

+[EXCP_FPE] = "Floating Point Exception",
+};
+
+const char *loongarch_exception_name(int32_t exception)
+{
+assert(excp_names[exception]);
+return excp_names[exception];
+}
+
+void QEMU_NORETURN do_raise_exception(CPULoongArchState *env,
+  uint32_t exception,
+  uintptr_t pc)
+{
+CPUState *cs = env_cpu(env);
+
+qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n",
+  __func__,
+  exception,
+  loongarch_exception_name(exception));
+cs->exception_index = exception;
+
+cpu_loop_exit_restore(cs, pc);
+}
+
+static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+
+env->pc = value;
+}
+
+#ifdef CONFIG_TCG
+static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
+  const TranslationBlock *tb)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+
+env->pc = tb->pc;
+}
+#endif /* CONFIG_TCG */
+
+static bool loongarch_cpu_has_work(CPUState *cs)
+{
+return true;


Note: this is only applicable to CONFIG_USER_ONLY, and needs to be 
changed in the following commits adding system emulation. To better 
convey your intention it may be better to use an #ifdef guard, something 
like this:


#ifndef CONFIG_USER_ONLY
#error System emulation TODO
#else
    return true;
#endif

(I'm not sure if this is okay in QEMU coding style, so please correct me 
if this isn't the case.)



+}
+
+static void loongarch_3a5000_initfn(Object *obj)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = >env;
+int i;
+
+for (i = 0; i < 21; i++) {
+env->cpucfg[i] = 0x0;
+}
+
+env->cpucfg[0] = 0x14c010;  /* PRID */
+
+uint32_t data = 0;
+data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
+data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
+data = 

Re: [PATCH v14 00/26] Add LoongArch linux-user emulation support

2022-01-08 Thread WANG Xuerui

Hi,

On 1/7/22 15:59, gaosong wrote:

Hi Richard.
On 2022/1/7 下午1:01, Richard Henderson wrote:

On 1/6/22 1:41 AM, Song Gao wrote:

Based-on:<20220106074740.1754661-1-gaos...@loongson.cn>

Hi all,

This series only support linux-user emulation.
More about LoongArch at:https://github.com/loongson/

The latest kernel:
   *https://github.com/loongson/linux/tree/loongarch-next

Patches need review:
   * 0018-linux-user-Add-LoongArch-specific-structures.patch
   * 0019-linux-user-Add-LoongArch-signal-support.patch


You're still blocked on no upstream kernel support.
As shown in patch 19, the kernel abi is still in flux.


We hope the kernel will support as soon as possible. but ...
It would be best if you could work toward getting full system 
emulation completed.  Then all of the basic cpu emulation can be 
merged and all you'd need to keep updating is the linux-user portions.



We are going to submit V4 system emulation, maybe tommorrow or next-week, and 
We'll keep updating the linux-user portions.


I believe what Richard meant is suggesting you to re-order your patches 
so that the CPU emulation part (first half of this series) and the 
system emulation part (Xiaojuan's series) would be combined to one new 
series, to be reviewed and merged independent of the still-unstable 
Linux ABI that's blocking this series at the moment. To "keep updating 
the linux-user portions" without re-arranging the series will just delay 
inclusion further, IMO.


In case the description above is not clear enough:

We basically have 3 parts for full LoongArch target support: (a) CPU 
emulation, (b) privileged architecture & hw emulation, and (c) 
linux-user emulation. Currently this series consists of (a) and (c), 
while Xiaojuan's series has (b). And the tcg-dev branch you seem to be 
staging your work at [1] has the same ordering: (a) then (c) then (b), 
which is consistent with Xiaojuan's series cover letter.


However, because (c) is blocked by kernel port upstreaming, (a) could 
not be merged, and by re-combining (a) with (b) we can speed up review 
and inclusion of things. This would require you to coordinate with 
Xiaojuan and reorder your patches in the tcg-dev branch, so that you can 
generate the right series to send.


[1]: https://github.com/loongson/qemu/tree/tcg-dev



Thanks
Song

r~

[PATCH v2] tcg/loongarch64: Support raising sigbus for user-only

2022-01-06 Thread WANG Xuerui
Based-on: <20220104021543.396571-1-richard.hender...@linaro.org>

Reviewed-by: Richard Henderson 
Signed-off-by: WANG Xuerui 
---

v2 -> v1:

- Dropped assert and added comment documenting reason to choose
  bstrpick.d over andi for the masking operation
- Collected R-b tag

 tcg/loongarch64/tcg-target.c.inc | 71 +++-
 tcg/loongarch64/tcg-target.h |  2 -
 2 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 9cd46c9be3..9b53549edb 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -29,6 +29,8 @@
  * THE SOFTWARE.
  */
 
+#include "../tcg-ldst.c.inc"
+
 #ifdef CONFIG_DEBUG_TCG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 "zero",
@@ -642,8 +644,6 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg 
val,
  */
 
 #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)
@@ -825,6 +825,61 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 
 return tcg_out_goto(s, l->raddr);
 }
+#else
+
+/*
+ * Alignment helpers for user-mode emulation
+ */
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
+   unsigned a_bits)
+{
+TCGLabelQemuLdst *l = new_ldst_label(s);
+
+l->is_ld = is_ld;
+l->addrlo_reg = addr_reg;
+
+/*
+ * Without micro-architecture details, we don't know which of bstrpick or
+ * andi is faster, so use bstrpick as it's not constrained by imm field
+ * width. (Not to say alignments >= 2^12 are going to happen any time
+ * soon, though)
+ */
+tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1);
+
+l->label_ptr[0] = s->code_ptr;
+tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0);
+
+l->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+/* resolve label address */
+if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+return false;
+}
+
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
+
+/* tail call, with the return address back inline. */
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr);
+tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld
+   : helper_unaligned_st), true);
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
 #endif /* CONFIG_SOFTMMU */
 
 /*
@@ -887,6 +942,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, TCGType type)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base;
 
@@ -903,6 +960,10 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, TCGType type)
 data_regl, addr_regl,
 s->code_ptr, label_ptr);
 #else
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, true, addr_regl, a_bits);
+}
 base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
 TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
 tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type);
@@ -941,6 +1002,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base;
 
@@ -958,6 +1021,10 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
 data_regl, addr_regl,
 s->code_ptr, label_ptr);
 #else
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, false, addr_regl, a_bits);
+}
 base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
 TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
 tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc);
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 05010805e7..d58a6162f2 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -171,9 +171,7 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 
 #define TCG_TARGET_DEFAULT_MO (0)
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
 
-- 
2.34.1




[PATCH] tcg/loongarch64: Support raising sigbus for user-only

2022-01-05 Thread WANG Xuerui
Based-on: <20220104021543.396571-1-richard.hender...@linaro.org>

Signed-off-by: WANG Xuerui 
---
 tcg/loongarch64/tcg-target.c.inc | 66 +++-
 tcg/loongarch64/tcg-target.h |  2 -
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 9cd46c9be3..900ca1ed8b 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -29,6 +29,8 @@
  * THE SOFTWARE.
  */
 
+#include "../tcg-ldst.c.inc"
+
 #ifdef CONFIG_DEBUG_TCG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 "zero",
@@ -642,8 +644,6 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg 
val,
  */
 
 #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)
@@ -825,6 +825,56 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 
 return tcg_out_goto(s, l->raddr);
 }
+#else
+
+/*
+ * Alignment helpers for user-mode emulation
+ */
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
+   unsigned a_bits)
+{
+TCGLabelQemuLdst *l = new_ldst_label(s);
+
+l->is_ld = is_ld;
+l->addrlo_reg = addr_reg;
+
+tcg_debug_assert(a_bits < TCG_TARGET_REG_BITS);
+tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1);
+
+l->label_ptr[0] = s->code_ptr;
+tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0);
+
+l->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+/* resolve label address */
+if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+return false;
+}
+
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
+
+/* tail call, with the return address back inline. */
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr);
+tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld
+   : helper_unaligned_st), true);
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
 #endif /* CONFIG_SOFTMMU */
 
 /*
@@ -887,6 +937,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, TCGType type)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base;
 
@@ -903,6 +955,10 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, TCGType type)
 data_regl, addr_regl,
 s->code_ptr, label_ptr);
 #else
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, true, addr_regl, a_bits);
+}
 base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
 TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
 tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type);
@@ -941,6 +997,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base;
 
@@ -958,6 +1016,10 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
 data_regl, addr_regl,
 s->code_ptr, label_ptr);
 #else
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, false, addr_regl, a_bits);
+}
 base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
 TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
 tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc);
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 05010805e7..d58a6162f2 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -171,9 +171,7 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 
 #define TCG_TARGET_DEFAULT_MO (0)
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
 
-- 
2.34.1




Re: [PATCH] linux-user: Fix trivial build error on loongarch64

2022-01-04 Thread WANG Xuerui
On 2022/1/4 21:02, Philippe Mathieu-Daudé wrote:

> When building using GCC 8.3.0 on loongarch64 (Loongnix) we get:
>
>   In file included from ../linux-user/signal.c:33:
>   ../linux-user/host/loongarch64/host-signal.h: In function 
> ‘host_signal_write’:
>   ../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only 
> be part of a statement and a declaration is not a statement
>  uint32_t sel = (insn >> 15) & 0b111;
>  ^~~~
>
> We don't use the 'sel' variable more than once, so drop it.
>
> Meson output for the record:
>
>   Host machine cpu family: loongarch64
>   Host machine cpu: loongarch64
>   C compiler for the host machine: cc (gcc 8.3.0 "cc (Loongnix 
> 8.3.0-6.lnd.vec.27) 8.3.0")
>   C linker for the host machine: cc ld.bfd 2.31.1-system
So this issue indeed only happens on the Loongson-provided toolchain
with the ancient 8.3.0 version of gcc, after all... I'd have to admit
that I was initially reluctant to even investigate this, given the
tendency of Loongson people not verifying things on upstream versions of
their own work, but...
>
> Fixes: ad812c3bd65 ("linux-user: Implement CPU-specific signal handler for 
> loongarch64 hosts")
> Reported-by: Song Gao 
> Suggested-by: Song Gao 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  linux-user/host/loongarch64/host-signal.h | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/linux-user/host/loongarch64/host-signal.h 
> b/linux-user/host/loongarch64/host-signal.h
> index 05e2c823717..7effa242515 100644
> --- a/linux-user/host/loongarch64/host-signal.h
> +++ b/linux-user/host/loongarch64/host-signal.h
> @@ -54,9 +54,7 @@ static inline bool host_signal_write(siginfo_t *info, 
> ucontext_t *uc)
>  }
>  break;
>  case 0b001110: /* indexed, atomic, bounds-checking memory operations */
> -uint32_t sel = (insn >> 15) & 0b111;
> -
> -switch (sel) {
> +switch ((insn >> 15) & 0b111) {
>  case 0b010: /* stx.b */
>  case 0b0101000: /* stx.h */
>  case 0b011: /* stx.w */

the fix is obvious enough, doesn't harm readability, and solves a real
problem for some (their toolchain being outdated is not their fault,
rather Loongson's).

So after fixing the commit message:

Reviewed-by: WANG Xuerui 

(Or do I just collect this patch and fix the commit message myself,
sending a pull request later? I'm new to QEMU maintenance procedure and
I'm still not quite sure if it is too heavyweight to have you send v2
for just a single typo and R-b tag collection.)




Re: [PATCH v4 0/7] Unaligned access for user only

2022-01-03 Thread WANG Xuerui

Hi Richard,

On 1/4/22 10:15, Richard Henderson wrote:

Version 3 was way back in August:

https://lore.kernel.org/qemu-devel/20210818191920.390759-1-richard.hender...@linaro.org/

Quite a few of the patches in there have been merged, but not all.

Based-on: <20211227150127.2659293-1-richard.hender...@linaro.org>

There are follow-on patch sets for arm, mips, and sparc, which I
will be refreshing soon.  Xuerui, I believe that tcg/loongarch
should be as simple as one of these five.
Thanks for the heads-up; I'll take care of implementing the loongarch64 
part in this week (or maybe next week in case of $DAY_JOB).



r~


Richard Henderson (7):
   tcg/i386: Support raising sigbus for user-only
   tcg/aarch64: Support raising sigbus for user-only
   tcg/ppc: Support raising sigbus for user-only
   tcg/riscv: Support raising sigbus for user-only
   tcg/s390x: Support raising sigbus for user-only
   tcg/tci: Support raising sigbus for user-only
   tests/tcg/multiarch: Add sigbus.c

  tcg/aarch64/tcg-target.h |   2 -
  tcg/i386/tcg-target.h|   2 -
  tcg/ppc/tcg-target.h |   2 -
  tcg/riscv/tcg-target.h   |   2 -
  tcg/s390x/tcg-target.h   |   2 -
  tcg/tci.c|  20 +--
  tests/tcg/multiarch/sigbus.c |  68 +++
  tcg/aarch64/tcg-target.c.inc |  91 +--
  tcg/i386/tcg-target.c.inc| 103 +--
  tcg/ppc/tcg-target.c.inc |  98 ++---
  tcg/riscv/tcg-target.c.inc   |  63 -
  tcg/s390x/tcg-target.c.inc   |  59 +++-
  12 files changed, 462 insertions(+), 50 deletions(-)
  create mode 100644 tests/tcg/multiarch/sigbus.c





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

2021-12-29 Thread WANG Xuerui

Hi,

On 12/30/21 11:11, gaosong wrote:


HI,

On 2021/12/21 下午1:41, WANG Xuerui wrote:

+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;
+}

We build qemu-x86_64 on LoongArch machine, but got an error,
../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only be 
part of a statement and a declaration is not a statement
  uint32_t sel = (insn >> 15) & 0b111;
  ^~~~
I think  we should define  'sel'  before:
     /* Detect store by reading the instruction at the program counter.  */
     switch ((insn >> 26) & 0b11) {
or
case 0b001110:
  {
           uint32_t set = ...;
   ...
  }
I can't reproduce the error on both my development machines (amd64 and 
loongarch64), so I wonder if the issue is related to your particular 
setup (i.e. compiler versions and such)?

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

2021-12-28 Thread WANG Xuerui

Hi Richard,

On 12/22/21 05:25, 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


Sorry for the delay in processing this (busy in end-of-year $DAY_JOB), I 
just noticed you've already pushed the gentoo-loongarch64-cross image to 
qemu-project container registry shortly after sending my revised patch.


The only thing missing in the original patch was two "optional: true" 
declarations in the "needs" section of the two cross build job stanzas; 
due to the long time required to re-build the image, you may just add 
the "optional: true"'s yourself and start to make use of the built 
image, and test the new patch at your leisure.





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

2021-12-28 Thread 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.

(In the original submission along with the rest of LoongArch TCG
patches, I forgot to make the dependency to the container build job
optional, thus CI was passing in my own fork but broke upstream. Fixed
for a 2nd take, and I also took the chance to update base image versions
and such.)

Signed-off-by: WANG Xuerui 
---

(Note to CI maintainers: obviously this image has to be built and pushed
manually, for everything to keep working. Sorry for the extra work
early-on, but the community around LoongArch still hope to upstream most
things during 2022 so eventually we will transition away from this.
This work is no hurry though, and Happy Holidays everyone!)

 .gitlab-ci.d/container-cross.yml  |  27 +
 .gitlab-ci.d/crossbuilds.yml  |  25 
 MAINTAINERS   |   2 +
 tests/docker/Makefile.include |  21 
 .../gentoo-loongarch64-cross.docker   |  21 
 .../build-toolchain.sh| 109 ++
 6 files changed, 205 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..ef19ade554 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -68,6 +68,31 @@ 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.
+#
+# Similar to hexagon, the container image is built outside of CI and manually
+# uploaded at the moment, so make the dependency to container build job
+# optional.
+cross-loongarch64-system:
+  extends: .cross_system_build_job
+  allow_failure: true
+  needs:
+job: loongarch64-cross-container
+optional: true
+  variables:
+IMAGE: gentoo-loongarch64-cross
+
+cross-loongarch64-user:
+  extends: .cross_user_build_job
+  allow_failure: true
+  needs:
+job: loongarch64-cross-container
+optional: true
+  variables:
+IMAGE: gentoo-loongarch64-cross
+
 cross-mips-system:
   extends: .cross_system_build_job
   needs:
diff --git a/MAINTAINERS b/MAINTAINERS
index 5456536805..6b42fe16c7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -

Re: [PATCH v2] audio: Add sndio backend

2021-12-23 Thread WANG Xuerui

Hi Alexandre,

On 12/17/21 17:38, Alexandre Ratchov wrote:

sndio is the native API used by OpenBSD, although it has been ported to
other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).

Signed-off-by: Brad Smith 
Signed-off-by: Alexandre Ratchov 
---

Thank you for the reviews and all the comments. Here's a second diff
with all the suggested changes:

- Replace ISC license by SPDX-License-Identifier header
- Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
- Drop outdated comment about the "size" argument of sndio_get_buffer_out()
- Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
- Set {read,write] methods to audio_generic_{read,write} (fixes craches)
- Check if backend is enabled in sndio_poll_event()
- Use https://sndio.org in description
- Mark options as available after 7.0 release (instead of 6.2)
- Describe sndio-specific options (dev, latency) in qemu-options.hx
- Add myself as reviewer to MAINTAINERS
- Style fixes: no space after function names, use 4-space indent
- Don't use "return foo()" if foo() returns void
- Include backend to audio_drivers_priority[]

Tested on OpenBSD, works as expected!

  MAINTAINERS|   5 +
  audio/audio.c  |   1 +
  audio/audio_template.h |   2 +
  audio/meson.build  |   1 +
  audio/sndioaudio.c | 555 +

Here we can see the file added is named "sndioaudio.c", so...

  meson.build|   9 +-
  meson_options.txt  |   4 +-
  qapi/audio.json|  25 +-
  qemu-options.hx|  16 ++
  tests/vm/freebsd   |   3 +
  10 files changed, 618 insertions(+), 3 deletions(-)
  create mode 100644 audio/sndioaudio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7543eb4d59..76bdad064f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
  X: audio/ossaudio.c
  X: audio/paaudio.c
  X: audio/sdlaudio.c
+X: audio/sndio.c

it should say "sndioaudio.c" here...

  X: audio/spiceaudio.c
  F: qapi/audio.json
  
@@ -2349,6 +2350,10 @@ R: Thomas Huth 

  S: Odd Fixes
  F: audio/sdlaudio.c
  
+Sndio Audio backend

+R: Alexandre Ratchov 
+F: audio/sndio.c

and here.

+
  Block layer core
  M: Kevin Wolf 
  M: Hanna Reitz 




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

2021-12-20 Thread 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é 
---
 .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-g

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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 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.34.0




[PATCH v11 25/31] tcg/loongarch64: Implement exit_tb/goto_tb

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




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

2021-12-20 Thread 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é 
---
 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.34.0




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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




[PATCH v11 26/31] tcg/loongarch64: Implement tcg_target_init

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




[PATCH v11 24/31] tcg/loongarch64: Implement tcg_target_qemu_prologue

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




[PATCH v11 27/31] tcg/loongarch64: Register the JIT

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 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, rZ);
@@ -954,6 +1073,18 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpco

[PATCH v11 19/31] tcg/loongarch64: Implement br/brcond ops

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 53 
 2 files changed, 54 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index fb56f3a295..367689c2e2 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, rZ)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 0ae193fba5..aedfc0df84 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -434,6 +434,44 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn 
opc,
 tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+/*
+ * Branch helpers
+ */
+
+static const struct {
+LoongArchInsn op;
+bool swap;
+} tcg_brcond_to_loongarch[] = {
+[TCG_COND_EQ] =  { OPC_BEQ,  false },
+[TCG_COND_NE] =  { OPC_BNE,  false },
+[TCG_COND_LT] =  { OPC_BGT,  true  },
+[TCG_COND_GE] =  { OPC_BLE,  true  },
+[TCG_COND_LE] =  { OPC_BLE,  false },
+[TCG_COND_GT] =  { OPC_BGT,  false },
+[TCG_COND_LTU] = { OPC_BGTU, true  },
+[TCG_COND_GEU] = { OPC_BLEU, true  },
+[TCG_COND_LEU] = { OPC_BLEU, false },
+[TCG_COND_GTU] = { OPC_BGTU, false }
+};
+
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+   TCGReg arg2, TCGLabel *l)
+{
+LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
+
+tcg_debug_assert(op != 0);
+
+if (tcg_brcond_to_loongarch[cond].swap) {
+TCGReg t = arg1;
+arg1 = arg2;
+arg2 = t;
+}
+
+/* all conditional branch insns belong to DJSk16-format */
+tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0);
+tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
+}
+
 /*
  * Entry-points
  */
@@ -456,6 +494,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
 break;
 
+case INDEX_op_br:
+tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0),
+  0);
+tcg_out_opc_b(s, 0);
+break;
+
+case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
+tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
+break;
+
 case INDEX_op_ext8s_i32:
 case INDEX_op_ext8s_i64:
 tcg_out_ext8s(s, a0, a1);
@@ -779,6 +828,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_goto_ptr:
 return C_O0_I1(r);
 
+case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
+return C_O0_I2(rZ, rZ);
+
 case INDEX_op_ext8s_i32:
 case INDEX_op_ext8s_i64:
 case INDEX_op_ext8u_i32:
-- 
2.34.0




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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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 */
+label->raddr = tcg_splitwx_to_rx(r

[PATCH v11 20/31] tcg/loongarch64: Implement setcond ops

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-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.34.0




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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 42 
 tcg/loongarch64/tcg-target.h |  8 +++---
 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.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 */
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
-- 
2.34.0




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

2021-12-20 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 91 
 tcg/loongarch64/tcg-target.h |  4 +-
 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.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:
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
-- 
2.34.0




  1   2   3   4   5   >