From patchwork Fri Oct 28 17:46:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jose Ricardo Ziviani X-Patchwork-Id: 688572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t5BDc48ddz9ssP for ; Sat, 29 Oct 2016 04:52:48 +1100 (AEDT) Received: from localhost ([::1]:51084 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c0BKg-0004v4-34 for incoming@patchwork.ozlabs.org; Fri, 28 Oct 2016 13:52:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44116) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c0BFR-0000mV-DZ for qemu-devel@nongnu.org; Fri, 28 Oct 2016 13:47:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c0BFN-0007C8-GC for qemu-devel@nongnu.org; Fri, 28 Oct 2016 13:47:21 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:51771 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c0BFN-0007C0-A1 for qemu-devel@nongnu.org; Fri, 28 Oct 2016 13:47:17 -0400 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u9SHhssg055186 for ; Fri, 28 Oct 2016 13:47:16 -0400 Received: from e24smtp01.br.ibm.com (e24smtp01.br.ibm.com [32.104.18.85]) by mx0b-001b2d01.pphosted.com with ESMTP id 26c9dcsmn0-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 28 Oct 2016 13:47:16 -0400 Received: from localhost by e24smtp01.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 28 Oct 2016 15:47:11 -0200 Received: from d24dlp02.br.ibm.com (9.18.248.206) by e24smtp01.br.ibm.com (10.172.0.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 28 Oct 2016 15:46:40 -0200 Received: from d24relay04.br.ibm.com (d24relay04.br.ibm.com [9.18.232.146]) by d24dlp02.br.ibm.com (Postfix) with ESMTP id 54DDE1DC0072 for ; Fri, 28 Oct 2016 13:46:33 -0400 (EDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.8.31.91]) by d24relay04.br.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u9SHkXvh37945520 for ; Fri, 28 Oct 2016 15:46:33 -0200 Received: from d24av01.br.ibm.com (localhost [127.0.0.1]) by d24av01.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u9SHkWM5009908 for ; Fri, 28 Oct 2016 15:46:33 -0200 Received: from pacoca.ibm.com ([9.80.239.17]) by d24av01.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u9SHkNLx009730; Fri, 28 Oct 2016 15:46:31 -0200 From: Jose Ricardo Ziviani To: qemu-devel@nongnu.org Date: Fri, 28 Oct 2016 15:46:22 -0200 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1477676782-21378-1-git-send-email-joserz@linux.vnet.ibm.com> References: <1477676782-21378-1-git-send-email-joserz@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16102817-1523-0000-0000-0000023FD2FB X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16102817-1524-0000-0000-0000298BF57E Message-Id: <1477676782-21378-4-git-send-email-joserz@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-10-28_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1610280300 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH Risu 3/3] Initial implemention for ppc64le X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Jose Ricardo Ziviani - This commit adds the initial implementation of ppc64le support (client and server) for Risu. Signed-off-by: Jose Ricardo Ziviani --- configure | 6 ++ risu_ppc64le.c | 92 ++++++++++++++++++++++++++ risu_reginfo_ppc64le.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++ risu_reginfo_ppc64le.h | 36 ++++++++++ test_ppc64le.s | 52 +++++++++++++++ 5 files changed, 361 insertions(+) create mode 100644 risu_ppc64le.c create mode 100644 risu_reginfo_ppc64le.c create mode 100644 risu_reginfo_ppc64le.h create mode 100644 test_ppc64le.s diff --git a/configure b/configure index 748b48a..3e239f3 100755 --- a/configure +++ b/configure @@ -22,6 +22,12 @@ guess_arch() { ARCH="arm" elif check_define __aarch64__ ; then ARCH="aarch64" + elif check_define __powerpc64__ ; then + if check_define __BIG_ENDIAN__; then + ARCH="ppc64" + else + ARCH="ppc64le" + fi else echo "This cpu is not supported by risu. Try -h. " >&2 exit 1 diff --git a/risu_ppc64le.c b/risu_ppc64le.c new file mode 100644 index 0000000..811dd77 --- /dev/null +++ b/risu_ppc64le.c @@ -0,0 +1,92 @@ +/****************************************************************************** + * 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_aarch64.c + * based on Peter Maydell's risu_arm.c + *****************************************************************************/ + +#include +#include +#include + +#include "risu.h" +#include "risu_reginfo_ppc64le.h" + +struct reginfo master_ri, apprentice_ri; + +void advance_pc(void *vuc) +{ + ucontext_t *uc = (ucontext_t*)vuc; + uc->uc_mcontext.regs->nip += 4; +} + +int send_register_info(int sock, void *uc) +{ + struct reginfo ri; + reginfo_init(&ri, uc); + return send_data_pkt(sock, &ri, sizeof(ri)); +} + +/* Read register info from the socket and compare it with that from the + * ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch. + * NB: called from a signal handler. + */ +int recv_and_compare_register_info(int sock, void *uc) +{ + int resp = 0; + reginfo_init(&master_ri, uc); + if (recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri))) { + printf("Packed mismatch\n"); + resp = 2; + + } else if (!reginfo_is_eq(&master_ri, &apprentice_ri, uc)) + { + /* mismatch */ + resp = 2; + } + else if (master_ri.faulting_insn == 0x5af1) + { + /* end of test */ + resp = 1; + } + else + { + /* either successful match or expected undef */ + resp = 0; + } + send_response_byte(sock, resp); + + return resp; +} + +/* Print a useful report on the status of the last comparison + * done in recv_and_compare_register_info(). This is called on + * exit, so need not restrict itself to signal-safe functions. + * Should return 0 if it was a good match (ie end of test) + * and 1 for a mismatch. + */ +int report_match_status(void) +{ + fprintf(stderr, "match status...\n"); + int resp = reginfo_is_eq(&master_ri, &apprentice_ri, NULL); + if (resp) { + fprintf(stderr, "\e[1;34mTest passed successfuly\e[0m\n"); + return 0; + } + + fprintf(stderr, "\n******************** [master reginfo]\n"); + reginfo_dump(&master_ri, 1); + + fprintf(stderr, "\n******************* [apprentice reginfo]\n"); + reginfo_dump(&apprentice_ri, 0); + + fprintf(stderr, "\e[1;31mmismatch!\e[0m\n"); + + return resp; +} diff --git a/risu_reginfo_ppc64le.c b/risu_reginfo_ppc64le.c new file mode 100644 index 0000000..b79ecfc --- /dev/null +++ b/risu_reginfo_ppc64le.c @@ -0,0 +1,175 @@ +/****************************************************************************** + * 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_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) +{ + ri->faulting_insn = *((uint32_t *)uc->uc_mcontext.regs->nip); + ri->prev_insn = *((uint32_t *)(uc->uc_mcontext.regs->nip - 4)); + ri->prev_addr = uc->uc_mcontext.regs->nip - 4; + + int i; + 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 *master, struct reginfo *apprentice, ucontext_t *uc) +{ + int i; + for (i = 0; i < 32; i++) + { + if (i == 1 || i == 13) + continue; + + if (master->gregs[i] != apprentice->gregs[i]) + { + fprintf(stderr, "\e[1;32mMismatch: \e[0mRegister r%d\n", i); + fprintf(stderr, "master: [%lx] - apprentice: [%lx]\n", + master->gregs[i], apprentice->gregs[i]); + return 0; + } + } + + if (master->gregs[XER] != apprentice->gregs[XER]) + { + fprintf(stderr, "\e[1;32mMismatch: \e[0mXER\n"); + fprintf(stderr, "master: [%lx] != apprentice: [%lx]\n", + master->gregs[XER], apprentice->gregs[XER]); + return 0; + } + + if ((master->gregs[CCR] & 0x10) != (apprentice->gregs[CCR] & 0x10)) + { + fprintf(stderr, "\e[1;32mMismatch: \e[0mCond. Register\n"); + fprintf(stderr, "master: [%lx] != apprentice: [%lx]\n", + master->gregs[CCR], apprentice->gregs[CCR]); + return 0; + } + + for (i = 0; i < 32; i++) + { + if (isnan(master->fpregs[i]) && isnan(apprentice->fpregs[i])) + continue; + + if (master->fpregs[i] != apprentice->fpregs[i]) + { + fprintf(stderr, "\e[1;32mMismatch: \e[0mRegister r%d\n", i); + fprintf(stderr, "master: [%f] != apprentice: [%f]\n", + master->fpregs[i], apprentice->fpregs[i]); + return 0; + } + } + + for (i = 0; i < 32; i++) + { + if (master->vrregs.vrregs[i][0] != apprentice->vrregs.vrregs[i][0] || + master->vrregs.vrregs[i][1] != apprentice->vrregs.vrregs[i][1] || + master->vrregs.vrregs[i][2] != apprentice->vrregs.vrregs[i][2] || + master->vrregs.vrregs[i][3] != apprentice->vrregs.vrregs[i][3]) + { + if (uc != NULL && (master->gregs[CCR] & 0x10)) { + uc->uc_mcontext.v_regs->vrregs[i][0] = apprentice->vrregs.vrregs[i][0]; + uc->uc_mcontext.v_regs->vrregs[i][1] = apprentice->vrregs.vrregs[i][1]; + uc->uc_mcontext.v_regs->vrregs[i][2] = apprentice->vrregs.vrregs[i][2]; + uc->uc_mcontext.v_regs->vrregs[i][3] = apprentice->vrregs.vrregs[i][3]; + return 1; + } + + fprintf(stderr, "\e[1;32mMismatch: \e[0mRegister vr%d\n", i); + fprintf(stderr, "master: [%x, %x, %x, %x] != apprentice: [%x, %x, %x, %x]\n", + master->vrregs.vrregs[i][0], master->vrregs.vrregs[i][1], + master->vrregs.vrregs[i][2], master->vrregs.vrregs[i][3], + apprentice->vrregs.vrregs[i][0], apprentice->vrregs.vrregs[i][1], + apprentice->vrregs.vrregs[i][2], apprentice->vrregs.vrregs[i][3]); + + 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]); + } +} diff --git a/risu_reginfo_ppc64le.h b/risu_reginfo_ppc64le.h new file mode 100644 index 0000000..9049455 --- /dev/null +++ b/risu_reginfo_ppc64le.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * 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 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); + +#endif /* RISU_REGINFO_PPC64LE_H */ diff --git a/test_ppc64le.s b/test_ppc64le.s new file mode 100644 index 0000000..bb30318 --- /dev/null +++ b/test_ppc64le.s @@ -0,0 +1,52 @@ +/***************************************************************************** + * 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: + * Claudio Fontana (Linaro) - initial implementation + * based on test_arm.s by Peter Maydell + *****************************************************************************/ + +/* Initialise the gp regs */ +li 0,0 +li 1,1 +li 2,2 +li 3,3 +li 4,4 +li 5,5 +li 6,6 +li 7,7 +li 8,8 +li 9,9 +li 10, 10 +li 11, 11 +li 12, 12 +li 13, 13 +li 14, 14 +li 15, 15 +li 16, 16 +li 17, 17 +li 18, 18 +li 19, 19 +li 20, 20 +li 21, 21 +li 22, 22 +li 23, 23 +li 24, 24 +li 25, 25 +li 26, 26 +li 27, 27 +li 28, 28 +li 29, 29 +li 30, 30 +li 31, 31 + +/* do compare. + * The manual says instr with bits (28,27) == 0 0 are UNALLOCATED + */ +.int 0x00005af0 +/* exit test */ +.int 0x00005af1