From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c3R2s-0006oA-Fa for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c3R2p-0001qx-79 for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:50 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:48795) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c3R2o-0001q1-UN for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:47 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id uA6HDgin140134 for ; Sun, 6 Nov 2016 12:15:46 -0500 Received: from e24smtp02.br.ibm.com (e24smtp02.br.ibm.com [32.104.18.86]) by mx0a-001b2d01.pphosted.com with ESMTP id 26hbx97wh6-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 06 Nov 2016 12:15:45 -0500 Received: from localhost by e24smtp02.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 6 Nov 2016 15:15:43 -0200 Received: from d24relay02.br.ibm.com (d24relay02.br.ibm.com [9.13.184.26]) by d24dlp02.br.ibm.com (Postfix) with ESMTP id 48EDB1DC0054 for ; Sun, 6 Nov 2016 12:15:41 -0500 (EST) Received: from d24av05.br.ibm.com (d24av05.br.ibm.com [9.18.232.44]) by d24relay02.br.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id uA6HFfCx24969698 for ; Sun, 6 Nov 2016 15:15:41 -0200 Received: from d24av05.br.ibm.com (localhost [127.0.0.1]) by d24av05.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id uA6HFer4003061 for ; Sun, 6 Nov 2016 15:15:41 -0200 From: Jose Ricardo Ziviani Date: Sun, 6 Nov 2016 15:15:23 -0200 In-Reply-To: <1478452528-13684-1-git-send-email-joserz@linux.vnet.ibm.com> References: <1478452528-13684-1-git-send-email-joserz@linux.vnet.ibm.com> Message-Id: <1478452528-13684-5-git-send-email-joserz@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH Risu v2 4/9] Implement lib to deal with PPC64 registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org This library is the initial effort to have PPC64 support for Risu. It implements functions to initialize, compare and print PPC64 registers. Signed-off-by: Jose Ricardo Ziviani --- risu_reginfo_ppc64le.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++ risu_reginfo_ppc64le.h | 40 ++++++++++ 2 files changed, 240 insertions(+) create mode 100644 risu_reginfo_ppc64le.c create mode 100644 risu_reginfo_ppc64le.h diff --git a/risu_reginfo_ppc64le.c b/risu_reginfo_ppc64le.c new file mode 100644 index 0000000..7a54eab --- /dev/null +++ b/risu_reginfo_ppc64le.c @@ -0,0 +1,200 @@ +/****************************************************************************** + * Copyright (c) IBM Corp, 2016 + * 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: + * Jose Ricardo Ziviani - initial implementation + * based on Claudio Fontana's risu_aarch64.c + * based on Peter Maydell's risu_arm.c + *****************************************************************************/ + +#include +#include +#include +#include + +#include "risu.h" +#include "risu_reginfo_ppc64le.h" + +#define XER 37 +#define CCR 38 + +/* reginfo_init: initialize with a ucontext */ +void reginfo_init(struct reginfo *ri, ucontext_t *uc) +{ + int i; + memset(ri, 0, sizeof(*ri)); + + ri->faulting_insn = *((uint32_t *)uc->uc_mcontext.regs->nip); + ri->nip = uc->uc_mcontext.regs->nip - image_start_address; + + for (i = 0; i < NGREG; i++) { + ri->gregs[i] = uc->uc_mcontext.gp_regs[i]; + } + + for (i = 0; i < NFPREG; i++) { + ri->fpregs[i] = uc->uc_mcontext.fp_regs[i]; + } + + for (i = 0; i < 32; i++) { + ri->vrregs.vrregs[i][0] = uc->uc_mcontext.v_regs->vrregs[i][0]; + ri->vrregs.vrregs[i][1] = uc->uc_mcontext.v_regs->vrregs[i][1]; + ri->vrregs.vrregs[i][2] = uc->uc_mcontext.v_regs->vrregs[i][2]; + ri->vrregs.vrregs[i][3] = uc->uc_mcontext.v_regs->vrregs[i][3]; + } + ri->vrregs.vscr = uc->uc_mcontext.v_regs->vscr; + ri->vrregs.vrsave = uc->uc_mcontext.v_regs->vrsave; +} + +/* reginfo_is_eq: compare the reginfo structs, returns nonzero if equal */ +int reginfo_is_eq(struct reginfo *m, struct reginfo *a, ucontext_t *uc) +{ + int i; + for (i = 0; i < 32; i++) { + if (i == 1 || i == 13) { + continue; + } + + if (m->gregs[i] != a->gregs[i]) { + return 0; + } + } + + if (m->gregs[XER] != a->gregs[XER]) { + return 0; + } + + if ((m->gregs[CCR] & 0x10) != (a->gregs[CCR] & 0x10)) { + return 0; + } + + for (i = 0; i < 32; i++) { + if (isnan(m->fpregs[i]) && isnan(a->fpregs[i])) { + continue; + } + + if (m->fpregs[i] != a->fpregs[i]) { + return 0; + } + } + + for (i = 0; i < 32; i++) { + if (m->vrregs.vrregs[i][0] != a->vrregs.vrregs[i][0] || + m->vrregs.vrregs[i][1] != a->vrregs.vrregs[i][1] || + m->vrregs.vrregs[i][2] != a->vrregs.vrregs[i][2] || + m->vrregs.vrregs[i][3] != a->vrregs.vrregs[i][3]) { + + if (uc != NULL && (m->gregs[CCR] & 0x10)) { + uc->uc_mcontext.v_regs->vrregs[i][0] = a->vrregs.vrregs[i][0]; + uc->uc_mcontext.v_regs->vrregs[i][1] = a->vrregs.vrregs[i][1]; + uc->uc_mcontext.v_regs->vrregs[i][2] = a->vrregs.vrregs[i][2]; + uc->uc_mcontext.v_regs->vrregs[i][3] = a->vrregs.vrregs[i][3]; + return 1; + } + return 0; + } + } + return 1; +} + +/* reginfo_dump: print state to a stream, returns nonzero on success */ +void reginfo_dump(struct reginfo *ri, int is_master) +{ + int i; + if (is_master) { + fprintf(stderr, " faulting insn \e[1;101;37m0x%x\e[0m\n", ri->faulting_insn); + fprintf(stderr, " prev insn \e[1;101;37m0x%x\e[0m\n", ri->prev_insn); + fprintf(stderr, " prev addr \e[1;101;37m0x%" PRIx64 "\e[0m\n\n", ri->prev_addr); + } + + for (i = 0; i < 16; i++) { + fprintf(stderr, "\tr%2d: %16lx\tr%2d: %16lx\n", i, ri->gregs[i], + i + 16, ri->gregs[i + 16]); + } + + fprintf(stderr, "\n"); + fprintf(stderr, "\tnip : %16lx\n", ri->gregs[32]); + fprintf(stderr, "\tmsr : %16lx\n", ri->gregs[33]); + fprintf(stderr, "\torig r3: %16lx\n", ri->gregs[34]); + fprintf(stderr, "\tctr : %16lx\n", ri->gregs[35]); + fprintf(stderr, "\tlnk : %16lx\n", ri->gregs[36]); + fprintf(stderr, "\txer : %16lx\n", ri->gregs[37]); + fprintf(stderr, "\tccr : %16lx\n", ri->gregs[38]); + fprintf(stderr, "\tmq : %16lx\n", ri->gregs[39]); + fprintf(stderr, "\ttrap : %16lx\n", ri->gregs[40]); + fprintf(stderr, "\tdar : %16lx\n", ri->gregs[41]); + fprintf(stderr, "\tdsisr : %16lx\n", ri->gregs[42]); + fprintf(stderr, "\tresult : %16lx\n", ri->gregs[43]); + fprintf(stderr, "\tdscr : %16lx\n\n", ri->gregs[44]); + + for (i = 0; i < 16; i++) { + fprintf(stderr, "\tf%2d: %.4f\tr%2d: %.4f\n", i, ri->fpregs[i], + i + 16, ri->fpregs[i + 16]); + } + fprintf(stderr, "\tfpscr: %f\n\n", ri->fpregs[32]); + + for (i = 0; i < 32; i++) { + fprintf(stderr, "vr%02d: %8x, %8x, %8x, %8x\n", i, + ri->vrregs.vrregs[i][0], ri->vrregs.vrregs[i][1], + ri->vrregs.vrregs[i][2], ri->vrregs.vrregs[i][3]); + } +} + +int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f) +{ + int i; + for (i = 0; i < 32; i++) { + if (i == 1 || i == 13) { + continue; + } + + if (m->gregs[i] != a->gregs[i]) { + fprintf(f, "Mismatch: Register r%d\n", i); + fprintf(f, "master: [%lx] - apprentice: [%lx]\n", + m->gregs[i], a->gregs[i]); + } + } + + if (m->gregs[XER] != a->gregs[XER]) { + fprintf(f, "Mismatch: XER\n"); + fprintf(f, "m: [%lx] != a: [%lx]\n", + m->gregs[XER], a->gregs[XER]); + } + + if (m->gregs[CCR] != a->gregs[CCR]) { + fprintf(f, "Mismatch: Cond. Register\n"); + fprintf(f, "m: [%lx] != a: [%lx]\n", + m->gregs[CCR], a->gregs[CCR]); + } + + for (i = 0; i < 32; i++) { + if (isnan(m->fpregs[i]) && isnan(a->fpregs[i])) { + continue; + } + + if (m->fpregs[i] != a->fpregs[i]) { + fprintf(f, "Mismatch: Register r%d\n", i); + fprintf(f, "m: [%f] != a: [%f]\n", + m->fpregs[i], a->fpregs[i]); + } + } + + for (i = 0; i < 32; i++) { + if (m->vrregs.vrregs[i][0] != a->vrregs.vrregs[i][0] || + m->vrregs.vrregs[i][1] != a->vrregs.vrregs[i][1] || + m->vrregs.vrregs[i][2] != a->vrregs.vrregs[i][2] || + m->vrregs.vrregs[i][3] != a->vrregs.vrregs[i][3]) { + + fprintf(f, "Mismatch: Register vr%d\n", i); + fprintf(f, "m: [%x, %x, %x, %x] != a: [%x, %x, %x, %x]\n", + m->vrregs.vrregs[i][0], m->vrregs.vrregs[i][1], + m->vrregs.vrregs[i][2], m->vrregs.vrregs[i][3], + a->vrregs.vrregs[i][0], a->vrregs.vrregs[i][1], + a->vrregs.vrregs[i][2], a->vrregs.vrregs[i][3]); + } + } + return !ferror(f); +} diff --git a/risu_reginfo_ppc64le.h b/risu_reginfo_ppc64le.h new file mode 100644 index 0000000..f0a3b88 --- /dev/null +++ b/risu_reginfo_ppc64le.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) 2013 Linaro 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: + * Jose Ricardo Ziviani - initial implementation + * based on Claudio Fontana's risu_reginfo_aarch64 + * based on Peter Maydell's risu_arm.c + *****************************************************************************/ + +#ifndef RISU_REGINFO_PPC64LE_H +#define RISU_REGINFO_PPC64LE_H + +struct reginfo +{ + uint32_t faulting_insn; + uint32_t prev_insn; + uint64_t nip; + uint64_t prev_addr; + gregset_t gregs; + fpregset_t fpregs; + vrregset_t vrregs; +}; + +/* initialize structure from a ucontext */ +void reginfo_init(struct reginfo *ri, ucontext_t *uc); + +/* return 1 if structs are equal, 0 otherwise. */ +int reginfo_is_eq(struct reginfo *r1, struct reginfo *r2, ucontext_t *uc); + +/* print reginfo state to a stream */ +void reginfo_dump(struct reginfo *ri, int is_master); + +/* reginfo_dump_mismatch: print mismatch details to a stream, ret nonzero=ok */ +int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f); + +#endif /* RISU_REGINFO_PPC64LE_H */ -- 2.7.4