aboutsummaryrefslogtreecommitdiff
path: root/risu_reginfo_ppc64.c
diff options
context:
space:
mode:
authorJose Ricardo Ziviani <joserz@linux.vnet.ibm.com>2017-05-25 16:10:23 -0300
committerPeter Maydell <peter.maydell@linaro.org>2017-05-30 15:13:37 +0100
commit353b55876e0dda84b198056af16e22b83306c4f8 (patch)
tree7af459c89e315d64ee09727b2e23138178047240 /risu_reginfo_ppc64.c
parentea41c01ae60024a2065cd7efea81069ad0abd46f (diff)
build: Add support to PowerPC BE
Essentialy the code for PowerPC BE and LE are the same, so this patch renames all *ppc64le.* files to *ppc64.* and reflects such in the Makefile. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> Message-id: 1495739423-32326-5-git-send-email-joserz@linux.vnet.ibm.com [PMM: dropped change which removes the user's ability to manually set the ARCH variable; deleted a now out of date comment] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'risu_reginfo_ppc64.c')
-rw-r--r--risu_reginfo_ppc64.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/risu_reginfo_ppc64.c b/risu_reginfo_ppc64.c
new file mode 100644
index 0000000..ae86263
--- /dev/null
+++ b/risu_reginfo_ppc64.c
@@ -0,0 +1,193 @@
+/******************************************************************************
+ * 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 <stdio.h>
+#include <ucontext.h>
+#include <string.h>
+#include <math.h>
+
+#include "risu.h"
+#include "risu_reginfo_ppc64.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)
+{
+ 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]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* 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 0x%x\n", ri->faulting_insn);
+ fprintf(f, " prev insn 0x%x\n", ri->prev_insn);
+ fprintf(f, " prev addr 0x%" PRIx64 "\n\n", ri->nip);
+
+ for (i = 0; i < 16; i++) {
+ fprintf(f, "\tr%2d: %16lx\tr%2d: %16lx\n", i, ri->gregs[i],
+ i + 16, ri->gregs[i + 16]);
+ }
+
+ fprintf(f, "\n");
+ fprintf(f, "\tnip : %16lx\n", ri->gregs[32]);
+ fprintf(f, "\tmsr : %16lx\n", ri->gregs[33]);
+ fprintf(f, "\torig r3: %16lx\n", ri->gregs[34]);
+ fprintf(f, "\tctr : %16lx\n", ri->gregs[35]);
+ fprintf(f, "\tlnk : %16lx\n", ri->gregs[36]);
+ fprintf(f, "\txer : %16lx\n", ri->gregs[37]);
+ fprintf(f, "\tccr : %16lx\n", ri->gregs[38]);
+ fprintf(f, "\tmq : %16lx\n", ri->gregs[39]);
+ fprintf(f, "\ttrap : %16lx\n", ri->gregs[40]);
+ fprintf(f, "\tdar : %16lx\n", ri->gregs[41]);
+ fprintf(f, "\tdsisr : %16lx\n", ri->gregs[42]);
+ fprintf(f, "\tresult : %16lx\n", ri->gregs[43]);
+ fprintf(f, "\tdscr : %16lx\n\n", ri->gregs[44]);
+
+ for (i = 0; i < 16; i++) {
+ fprintf(f, "\tf%2d: %.4f\tr%2d: %.4f\n", i, ri->fpregs[i],
+ i + 16, ri->fpregs[i + 16]);
+ }
+ fprintf(f, "\tfpscr: %f\n\n", ri->fpregs[32]);
+
+ for (i = 0; i < 32; i++) {
+ fprintf(f, "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]);
+ }
+
+ return !ferror(f);
+}
+
+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);
+}