From patchwork Wed Sep 14 08:42:40 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 114652 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1FC0FB712A for ; Wed, 14 Sep 2011 21:03:20 +1000 (EST) Received: from localhost ([::1]:59482 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R3l4B-0000DV-Me for incoming@patchwork.ozlabs.org; Wed, 14 Sep 2011 04:43:35 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42307) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R3l3N-0007NQ-Qg for qemu-devel@nongnu.org; Wed, 14 Sep 2011 04:43:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R3l3F-0000Vc-Ki for qemu-devel@nongnu.org; Wed, 14 Sep 2011 04:42:45 -0400 Received: from cantor2.suse.de ([195.135.220.15]:36893 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R3l3F-0000UO-7I; Wed, 14 Sep 2011 04:42:37 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 1BA628FC93; Wed, 14 Sep 2011 10:42:36 +0200 (CEST) From: Alexander Graf To: qemu-devel Developers Date: Wed, 14 Sep 2011 10:42:40 +0200 Message-Id: <1315989802-18753-17-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1315989802-18753-1-git-send-email-agraf@suse.de> References: <1315989802-18753-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: Blue Swirl , qemu-ppc@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PATCH 16/58] PPC: KVM: Add generic function to read host clockfreq X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We need to find out the host's clock-frequency when running on KVM, so let's export a respective function. Signed-off-by: Alexander Graf --- v1 -> v2: - enable 64bit values --- target-ppc/kvm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ target-ppc/kvm_ppc.h | 1 + 2 files changed, 68 insertions(+), 0 deletions(-) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 21f35af..77b98c4 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -14,6 +14,7 @@ * */ +#include #include #include #include @@ -38,6 +39,8 @@ do { } while (0) #endif +#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/" + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -509,6 +512,70 @@ uint32_t kvmppc_get_tbfreq(void) return retval; } +/* Try to find a device tree node for a CPU with clock-frequency property */ +static int kvmppc_find_cpu_dt(char *buf, int buf_len) +{ + struct dirent *dirp; + DIR *dp; + + if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) { + printf("Can't open directory " PROC_DEVTREE_CPU "\n"); + return -1; + } + + buf[0] = '\0'; + while ((dirp = readdir(dp)) != NULL) { + FILE *f; + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, + dirp->d_name); + f = fopen(buf, "r"); + if (f) { + snprintf(buf, buf_len, "%s%s", PROC_DEVTREE_CPU, dirp->d_name); + fclose(f); + break; + } + buf[0] = '\0'; + } + closedir(dp); + if (buf[0] == '\0') { + printf("Unknown host!\n"); + return -1; + } + + return 0; +} + +uint64_t kvmppc_get_clockfreq(void) +{ + char buf[512]; + uint32_t tb[2]; + FILE *f; + int len; + + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { + return 0; + } + + strncat(buf, "/clock-frequency", sizeof(buf) - strlen(buf)); + + f = fopen(buf, "rb"); + if (!f) { + return -1; + } + + len = fread(tb, sizeof(tb[0]), 2, f); + fclose(f); + switch (len) { + case 1: + /* freq is only a single cell */ + return tb[0]; + case 2: + return *(uint64_t*)tb; + } + + return 0; +} + int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) { uint32_t *hc = (uint32_t*)buf; diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 2f32249..7c08c0f 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -23,6 +23,7 @@ int kvmppc_read_host_property(const char *node_path, const char *prop, #endif uint32_t kvmppc_get_tbfreq(void); +uint64_t kvmppc_get_clockfreq(void); int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len); int kvmppc_set_interrupt(CPUState *env, int irq, int level);