From patchwork Mon May 21 07:24:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 160329 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BCAFAB6F62 for ; Mon, 21 May 2012 17:24:22 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756129Ab2EUHYO (ORCPT ); Mon, 21 May 2012 03:24:14 -0400 Received: from gate.crashing.org ([63.228.1.57]:32923 "EHLO gate.crashing.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755843Ab2EUHYK (ORCPT ); Mon, 21 May 2012 03:24:10 -0400 Received: from [127.0.0.1] (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id q4L7O2wH025330; Mon, 21 May 2012 02:24:03 -0500 Message-ID: <1337585042.2779.4.camel@pasglop> Subject: [PATCH] spapr: Add "memop" hypercall From: Benjamin Herrenschmidt To: Alexander Graf Cc: kvm@vger.kernel.org, kvm-ppc Date: Mon, 21 May 2012 17:24:02 +1000 X-Mailer: Evolution 3.2.3-0ubuntu6 Mime-Version: 1.0 Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org This adds a kvm-specific hypervisor call to the pseries machine which allows to do what amounts to memmove, memcpy and xor over regions of physical memory such as the framebuffer. This is the simplest way to get usable framebuffer speed from SLOF since the framebuffer isn't mapped in the VRMA and so would otherwise require an hcall per 8 bytes access. The performance is still not great but usable, and can be improved with a more complex implementation of the hcall itself if needed. Signed-off-by: Benjamin Herrenschmidt --- hw/spapr.h | 3 ++- hw/spapr_hcall.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/hw/spapr.h b/hw/spapr.h index 7c497aa..0343f33 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -264,7 +264,8 @@ typedef struct sPAPREnvironment { */ #define KVMPPC_HCALL_BASE 0xf000 #define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) -#define KVMPPC_HCALL_MAX KVMPPC_H_RTAS +#define KVMPPC_H_LOGICAL_MEMOP (KVMPPC_HCALL_BASE + 0x1) +#define KVMPPC_HCALL_MAX KVMPPC_H_LOGICAL_MEMOP extern sPAPREnvironment *spapr; diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c index 94bb504..c5c26dc 100644 --- a/hw/spapr_hcall.c +++ b/hw/spapr_hcall.c @@ -608,6 +608,54 @@ static target_ulong h_logical_store(CPUPPCState *env, sPAPREnvironment *spapr, return H_PARAMETER; } +static target_ulong h_logical_memop(CPUPPCState *env, sPAPREnvironment *spapr, + target_ulong opcode, target_ulong *args) +{ + target_ulong dst = args[0]; /* Destination address */ + target_ulong src = args[1]; /* Source address */ + target_ulong esize = args[2]; /* Element size (0=1,1=2,2=4,3=8) */ + target_ulong count = args[3]; /* Element count */ + target_ulong op = args[4]; /* 0 = copy, 1 = invert */ + uint64_t tmp; + unsigned int mask = (1 << esize) - 1; + int step = 1 << esize; + + if (count > 0x80000000) + return H_PARAMETER; + + if ((dst & mask) || (src & mask)) + return H_PARAMETER; + + if (dst >= src && dst < (src + (count << esize))) { + dst = dst + ((count - 1) << esize); + src = src + ((count - 1) << esize); + step = -step; + } + + while(count--) { + switch (esize) { + case 0: tmp = ldub_phys(src); break; + case 1: tmp = lduw_phys(src); break; + case 2: tmp = ldl_phys(src); break; + case 3: tmp = ldq_phys(src); break; + default: + return H_PARAMETER; + } + if (op) + tmp = ~tmp; + switch (esize) { + case 0: stb_phys(dst, tmp); break; + case 1: stw_phys(dst, tmp); break; + case 2: stl_phys(dst, tmp); break; + case 3: stq_phys(dst, tmp); break; + } + dst = dst + step; + src = src + step; + } + + return H_SUCCESS; +} + static target_ulong h_logical_icbi(CPUPPCState *env, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { @@ -700,6 +748,7 @@ static void hypercall_register_types(void) spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store); spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi); spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf); + spapr_register_hypercall(KVMPPC_H_LOGICAL_MEMOP, h_logical_memop); /* qemu/KVM-PPC specific hcalls */ spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);