qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RISU PATCH 2/5] loongarch: Add LoongArch basic test support


From: Song Gao
Subject: [RISU PATCH 2/5] loongarch: Add LoongArch basic test support
Date: Sat, 17 Sep 2022 15:43:14 +0800

This patch adds LoongArch server, client support, and basic test file.

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 risu_loongarch64.c         |  50 ++++++++++
 risu_reginfo_loongarch64.c | 183 +++++++++++++++++++++++++++++++++++++
 risu_reginfo_loongarch64.h |  25 +++++
 test_loongarch64.s         |  92 +++++++++++++++++++
 4 files changed, 350 insertions(+)
 create mode 100644 risu_loongarch64.c
 create mode 100644 risu_reginfo_loongarch64.c
 create mode 100644 risu_reginfo_loongarch64.h
 create mode 100644 test_loongarch64.s

diff --git a/risu_loongarch64.c b/risu_loongarch64.c
new file mode 100644
index 0000000..24599e1
--- /dev/null
+++ b/risu_loongarch64.c
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * Copyright (c) 2022 Loongson Technology Corporation Limited
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     based on Peter Maydell's risu_arm.c
+ *****************************************************************************/
+
+#include <asm/types.h>
+#include <signal.h>
+#include <asm/ucontext.h>
+
+#include "risu.h"
+
+void advance_pc(void *vuc)
+{
+    struct ucontext *uc = vuc;
+    uc->uc_mcontext.sc_pc += 4;
+}
+
+void set_ucontext_paramreg(void *vuc, uint64_t value)
+{
+    struct ucontext *uc = vuc;
+    uc->uc_mcontext.sc_regs[4] = value;
+}
+
+uint64_t get_reginfo_paramreg(struct reginfo *ri)
+{
+    return ri->regs[4];
+}
+
+int get_risuop(struct reginfo *ri)
+{
+    /* Return the risuop we have been asked to do
+     * (or -1 if this was a SIGILL for a non-risuop insn)
+     */
+    uint32_t insn = ri->faulting_insn;
+    uint32_t op = insn & 0xf;
+    uint32_t key = insn & ~0xf;
+    uint32_t risukey = 0x000001f0;
+    return (key != risukey) ? -1 : op;
+}
+
+uintptr_t get_pc(struct reginfo *ri)
+{
+   return ri->pc;
+}
diff --git a/risu_reginfo_loongarch64.c b/risu_reginfo_loongarch64.c
new file mode 100644
index 0000000..af6ab77
--- /dev/null
+++ b/risu_reginfo_loongarch64.c
@@ -0,0 +1,183 @@
+/******************************************************************************
+ * Copyright (c) 2022 Loongson Technology Corporation Limited
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     based on Peter Maydell's risu_reginfo_arm.c
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <asm/types.h>
+#include <signal.h>
+#include <asm/ucontext.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <sys/prctl.h>
+
+#include "risu.h"
+#include "risu_reginfo_loongarch64.h"
+
+const struct option * const arch_long_opts;
+const char * const arch_extra_help;
+
+struct _ctx_layout {
+        struct sctx_info *addr;
+        unsigned int size;
+};
+
+struct extctx_layout {
+        unsigned long size;
+        unsigned int flags;
+        struct _ctx_layout fpu;
+        struct _ctx_layout end;
+};
+
+void process_arch_opt(int opt, const char *arg)
+{
+    abort();
+}
+
+void arch_init(void)
+{
+}
+
+int reginfo_size(struct reginfo *ri)
+{
+    return sizeof(*ri);
+}
+
+static int parse_extcontext(struct sigcontext *sc, struct extctx_layout 
*extctx)
+{
+    uint32_t magic, size;
+    struct sctx_info *info = (struct sctx_info *)&sc->sc_extcontext;
+
+    while(1) {
+        magic = (uint32_t)info->magic;
+        size =  (uint32_t)info->size;
+        switch (magic) {
+        case 0: /* END*/
+            return 0;
+        case FPU_CTX_MAGIC:
+            if (size < (sizeof(struct sctx_info) +
+                        sizeof(struct fpu_context))) {
+                return -1;
+            }
+            extctx->fpu.addr = info;
+            break;
+        default:
+            return -1;
+       }
+       info = (struct sctx_info *)((char *)info +size);
+    }
+    return 0;
+}
+
+/* reginfo_init: initialize with a ucontext */
+void reginfo_init(struct reginfo *ri, ucontext_t *context)
+{
+    int i;
+    struct ucontext *uc = (struct ucontext *)context;
+    struct extctx_layout extctx;
+
+    memset(&extctx, 0, sizeof(struct extctx_layout));
+    memset(ri, 0, sizeof(*ri));
+
+    for (i = 1; i < 32; i++) {
+        ri->regs[i] = uc->uc_mcontext.sc_regs[i]; //sp:r3, tp:r2
+    }
+
+    ri->regs[2] = 0xdeadbeefdeadbeef;
+    ri->pc = uc->uc_mcontext.sc_pc - (unsigned long)image_start_address;
+    ri->flags = uc->uc_mcontext.sc_flags;
+    ri->faulting_insn = *(uint32_t *)uc->uc_mcontext.sc_pc;
+
+    parse_extcontext(&uc->uc_mcontext, &extctx);
+    if (extctx.fpu.addr) {
+        struct sctx_info *info = extctx.fpu.addr;
+        struct fpu_context *fpu_ctx = (struct fpu_context *)((char *)info +
+                                       sizeof(struct sctx_info));
+        for(i = 0; i < 32; i++) {
+           ri->fpregs[i] = fpu_ctx->regs[i];
+        }
+       ri->fcsr = fpu_ctx->fcsr;
+       ri->fcc = fpu_ctx->fcc;
+    }
+}
+
+/* reginfo_is_eq: compare the reginfo structs, returns nonzero if equal */
+int reginfo_is_eq(struct reginfo *r1, struct reginfo *r2)
+{
+    return !memcmp(r1, r2, sizeof(*r1));
+}
+
+/* reginfo_dump: print state to a stream, returns nonzero on success */
+int reginfo_dump(struct reginfo *ri, FILE * f)
+{
+    int i;
+    fprintf(f, "  faulting insn %08x\n", ri->faulting_insn);
+
+    for (i = 0; i < 32; i++) {
+        fprintf(f, "  r%-2d    : %016" PRIx64 "\n", i, ri->regs[i]);
+    }
+
+    fprintf(f, "  pc     : %016" PRIx64 "\n", ri->pc);
+    fprintf(f, "  flags  : %08x\n", ri->flags);
+    fprintf(f, "  fcc    : %016" PRIx64 "\n", ri->fcc);
+    fprintf(f, "  fcsr   : %08x\n", ri->fcsr);
+
+    for (i = 0; i < 32; i++) {
+        fprintf(f, "  f%-2d    : %016lx\n", i, ri->fpregs[i]);
+    }
+
+    return !ferror(f);
+}
+
+/* reginfo_dump_mismatch: print mismatch details to a stream, ret nonzero=ok */
+int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE * f)
+{
+    int i;
+    fprintf(f, "mismatch detail (master : apprentice):\n");
+    if (m->faulting_insn != a->faulting_insn) {
+        fprintf(f, "  faulting insn mismatch %08x vs %08x\n",
+                m->faulting_insn, a->faulting_insn);
+    }
+    /* r2:tp, r3:sp */
+    for (i = 0; i < 32; i++) {
+        if (m->regs[i] != a->regs[i]) {
+            fprintf(f, "  r%-2d    : %016" PRIx64 " vs %016" PRIx64 "\n",
+                    i, m->regs[i], a->regs[i]);
+        }
+    }
+
+    if (m->pc != a->pc) {
+        fprintf(f, "  pc     : %016" PRIx64 " vs %016" PRIx64 "\n",
+                m->pc, a->pc);
+    }
+    if (m->flags != a->flags) {
+        fprintf(f, "  flags  : %08x vs %08x\n", m->flags, a->flags);
+    }
+    if (m->fcc != a->fcc) {
+        fprintf(f, "  fcc    : %016" PRIx64 " vs %016" PRIx64 "\n",
+                m->fcc, a->fcc);
+    }
+    if (m->fcsr != a->fcsr) {
+        fprintf(f, "  fcsr   : %08x vs %08x\n", m->fcsr, a->fcsr);
+    }
+
+    for (i = 0; i < 32; i++) {
+        if (m->fpregs[i]!= a->fpregs[i]) {
+            fprintf(f, "  f%-2d    : %016lx vs %016lx\n",
+                    i, m->fpregs[i], a->fpregs[i]);
+        }
+    }
+
+    return !ferror(f);
+}
diff --git a/risu_reginfo_loongarch64.h b/risu_reginfo_loongarch64.h
new file mode 100644
index 0000000..b6c5aaa
--- /dev/null
+++ b/risu_reginfo_loongarch64.h
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * Copyright (c) 2022 Loongson Technology Corporation Limited
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     based on Peter Maydell's risu_reginfo_arm.h
+ *****************************************************************************/
+
+#ifndef RISU_REGINFO_LOONGARCH64_H
+#define RISU_REGINFO_LOONGARCH64_H
+
+struct reginfo {
+    uint64_t regs[32];
+    uint64_t pc;
+    uint64_t fcc;
+    uint32_t flags;
+    uint32_t fcsr;
+    uint32_t faulting_insn;
+    uint64_t fpregs[32];
+};
+
+#endif /* RISU_REGINFO_LOONGARCH64_H */
diff --git a/test_loongarch64.s b/test_loongarch64.s
new file mode 100644
index 0000000..431416d
--- /dev/null
+++ b/test_loongarch64.s
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ * Copyright (c) 2022 Loongson Technology Corporation Limited
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * rhich accompanies this distribution, and is available at
+ * http://rrr.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     based on test_arm.s by Peter Maydell
+ *****************************************************************************/
+
+/* Initialise the gp regs */
+# $r0 is always 0
+addi.w $r1, $r0, 1
+#r2 tp skip r2
+#r3 sp
+addi.w $r3, $r0, 3
+addi.w $r4, $r0, 4
+addi.w $r5, $r0, 5
+addi.w $r6, $r0, 6
+addi.w $r7, $r0, 7
+addi.w $r8, $r0, 8
+addi.w $r9, $r0, 9
+addi.w $r10, $r0, 10
+addi.w $r11, $r0, 11
+addi.w $r12, $r0, 12
+addi.w $r13, $r0, 13
+addi.w $r14, $r0, 14
+addi.w $r15, $r0, 15
+addi.w $r16, $r0, 16
+addi.w $r17, $r0, 17
+addi.w $r18, $r0, 18
+addi.w $r19, $r0, 19
+addi.w $r20, $r0, 20
+addi.w $r21, $r0, 21
+addi.w $r22, $r0, 22
+addi.w $r23, $r0, 23
+addi.w $r24, $r0, 24
+addi.w $r25, $r0, 25
+addi.w $r26, $r0, 26
+addi.w $r27, $r0, 27
+addi.w $r28, $r0, 28
+addi.w $r29, $r0, 29
+addi.w $r30, $r0, 30
+addi.w $r31, $r0, 31
+
+/* Initialise the fp regs */
+movgr2fr.d $f0, $r0
+movgr2fr.d $f1, $r1
+movgr2fr.d $f2, $r0
+movgr2fr.d $f3, $r0
+movgr2fr.d $f4, $r4
+movgr2fr.d $f5, $r5
+movgr2fr.d $f6, $r6
+movgr2fr.d $f7, $r7
+movgr2fr.d $f8, $r8
+movgr2fr.d $f9, $r9
+movgr2fr.d $f10, $r10
+movgr2fr.d $f11, $r11
+movgr2fr.d $f12, $r12
+movgr2fr.d $f13, $r13
+movgr2fr.d $f14, $r14
+movgr2fr.d $f15, $r15
+movgr2fr.d $f16, $r16
+movgr2fr.d $f17, $r17
+movgr2fr.d $f18, $r18
+movgr2fr.d $f19, $r19
+movgr2fr.d $f20, $r20
+movgr2fr.d $f21, $r21
+movgr2fr.d $f22, $r22
+movgr2fr.d $f23, $r23
+movgr2fr.d $f24, $r24
+movgr2fr.d $f25, $r25
+movgr2fr.d $f26, $r26
+movgr2fr.d $f27, $r27
+movgr2fr.d $f28, $r28
+movgr2fr.d $f29, $r29
+movgr2fr.d $f30, $r30
+movgr2fr.d $f31, $r31
+movgr2cf $fcc0, $r0
+movgr2cf $fcc1, $r0
+movgr2cf $fcc2, $r0
+movgr2cf $fcc3, $r0
+movgr2cf $fcc4, $r0
+movgr2cf $fcc5, $r0
+movgr2cf $fcc6, $r0
+movgr2cf $fcc7, $r0
+
+/* do compare. */
+.int 0x000001f0
+/* exit test */
+.int 0x000001f1
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]