From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45699) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c3R2w-0006qW-75 for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c3R2s-0001tx-U1 for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:54 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:54808 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 1c3R2s-0001tY-Op for qemu-devel@nongnu.org; Sun, 06 Nov 2016 12:15:50 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id uA6HDk6f086623 for ; Sun, 6 Nov 2016 12:15:50 -0500 Received: from e24smtp04.br.ibm.com (e24smtp04.br.ibm.com [32.104.18.25]) by mx0a-001b2d01.pphosted.com with ESMTP id 26j7pyjbhd-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 06 Nov 2016 12:15:50 -0500 Received: from localhost by e24smtp04.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 6 Nov 2016 15:15:48 -0200 Received: from d24relay02.br.ibm.com (d24relay02.br.ibm.com [9.13.184.26]) by d24dlp01.br.ibm.com (Postfix) with ESMTP id C9F80352005C for ; Sun, 6 Nov 2016 12:15:17 -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 uA6HFjPa31457692 for ; Sun, 6 Nov 2016 15:15:45 -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 uA6HFjVe003134 for ; Sun, 6 Nov 2016 15:15:45 -0200 From: Jose Ricardo Ziviani Date: Sun, 6 Nov 2016 15:15:25 -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-7-git-send-email-joserz@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH Risu v2 6/9] Implement initial support for PPC64 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org This implementation drives both client and server sides with PPC64 specific code. It basically reads instructions from both sides and compare them. Signed-off-by: Jose Ricardo Ziviani --- risu_ppc64le.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 risu_ppc64le.c diff --git a/risu_ppc64le.c b/risu_ppc64le.c new file mode 100644 index 0000000..9c1fafd --- /dev/null +++ b/risu_ppc64le.c @@ -0,0 +1,158 @@ +/****************************************************************************** + * 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 "risu.h" +#include "risu_reginfo_ppc64le.h" + +struct reginfo master_ri, apprentice_ri; +static int mem_used = 0; +static int packet_mismatch = 0; + +uint8_t apprentice_memblock[MEMBLOCKLEN]; + +void advance_pc(void *vuc) +{ + ucontext_t *uc = (ucontext_t*)vuc; + uc->uc_mcontext.regs->nip += 4; +} + +void set_x0(void *vuc, uint64_t x0) +{ + ucontext_t *uc = vuc; + uc->uc_mcontext.gp_regs[0] = x0; +} + +static int get_risuop(uint32_t insn) +{ + uint32_t op = insn & 0xf; + uint32_t key = insn & ~0xf; + uint32_t risukey = 0x00005af0; + return (key != risukey) ? -1 : op; +} + +int send_register_info(int sock, void *uc) +{ + struct reginfo ri; + int op; + + reginfo_init(&ri, uc); + op = get_risuop(ri.faulting_insn); + + switch (op) { + case OP_COMPARE: + case OP_TESTEND: + default: + return send_data_pkt(sock, &ri, sizeof(ri)); + case OP_SETMEMBLOCK: + memblock = (void*)ri.gregs[0]; + break; + case OP_GETMEMBLOCK: + set_x0(uc, ri.gregs[0] + (uintptr_t)memblock); + break; + case OP_COMPAREMEM: + return send_data_pkt(sock, memblock, MEMBLOCKLEN); + break; + } + return 0; +} + +/* 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; + int op; + + reginfo_init(&master_ri, uc); + op = get_risuop(master_ri.faulting_insn); + + switch (op) { + case OP_COMPARE: + case OP_TESTEND: + default: + if (recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri))) { + packet_mismatch = 1; + resp = 2; + } else if (!reginfo_is_eq(&master_ri, &apprentice_ri, uc)) { + resp = 2; + } + else if (op == OP_TESTEND) { + resp = 1; + } + send_response_byte(sock, resp); + break; + case OP_SETMEMBLOCK: + memblock = (void*)master_ri.gregs[0]; + break; + case OP_GETMEMBLOCK: + set_x0(uc, master_ri.gregs[0] + (uintptr_t)memblock); + break; + case OP_COMPAREMEM: + mem_used = 1; + if (recv_data_pkt(sock, apprentice_memblock, MEMBLOCKLEN)) { + packet_mismatch = 1; + resp = 2; + } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) { + resp = 2; + } + send_response_byte(sock, resp); + break; + } + 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) +{ + int resp = 0; + fprintf(stderr, "match status...\n"); + + if (packet_mismatch) { + fprintf(stderr, "packet mismatch (probably disagreement " + "about UNDEF on load/store)\n"); + fprintf(stderr, "master reginfo:\n"); + reginfo_dump(&master_ri, 0); + } + if (!reginfo_is_eq(&master_ri, &apprentice_ri, NULL)) { + fprintf(stderr, "mismatch on regs!\n"); + resp = 1; + } + if (mem_used && memcmp(memblock, &apprentice_memblock, MEMBLOCKLEN) != 0) { + fprintf(stderr, "mismatch on memory!\n"); + resp = 1; + } + if (!resp) { + fprintf(stderr, "match!\n"); + return 0; + } + + fprintf(stderr, "master reginfo:\n"); + reginfo_dump(&master_ri, 1); + + fprintf(stderr, "apprentice reginfo:\n"); + reginfo_dump(&apprentice_ri, 0); + + reginfo_dump_mismatch(&master_ri, &apprentice_ri, stderr); + return resp; +} -- 2.7.4