From patchwork Sun Oct 30 20:23:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 122674 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 C5735B6F76 for ; Mon, 31 Oct 2011 08:10:48 +1100 (EST) Received: from localhost ([::1]:59833 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKbnL-0005Nx-SZ for incoming@patchwork.ozlabs.org; Sun, 30 Oct 2011 16:15:51 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43301) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKbmL-0003SN-GS for qemu-devel@nongnu.org; Sun, 30 Oct 2011 16:14:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RKbmD-0002oZ-Ew for qemu-devel@nongnu.org; Sun, 30 Oct 2011 16:14:49 -0400 Received: from cantor2.suse.de ([195.135.220.15]:60672 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKbmC-0002nR-Ea; Sun, 30 Oct 2011 16:14:40 -0400 Received: from relay1.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 7F17A8EE65; Sun, 30 Oct 2011 21:14:38 +0100 (CET) From: Alexander Graf To: qemu-devel@nongnu.org Date: Sun, 30 Oct 2011 21:23:02 +0100 Message-Id: <1320006193-15219-12-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1320006193-15219-1-git-send-email-agraf@suse.de> References: <1320006193-15219-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, David Gibson Subject: [Qemu-devel] [PATCH 11/22] ppc: Remove broken partial PVR matching 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 From: David Gibson The ppc target contains a ppc_find_by_pvr() function, which looks up a CPU spec based on a PVR (that is, based on the value in the target cpu's Processor Version Register). PVR values contain information on both the cpu model (upper 16 bits, usually) and on the precise revision (low 16 bits, usually). ppc_find_by_pvr, as well as making exact PVR matches, attempts to find "close" PVR matches, when we don't have a CPU spec for the exact revision specified. This sounds like a good idea, execpt that the current logic is completely nonsensical. It seems to assume CPU families are subdivided bit by bit in the PVR in a way they just aren't. Specifically, it requires a match on all bits of the specified pvr up to the last non-zero bit. This has the bizarre effect that when the low bits are simply a sequential revision number (a common though not universal pattern), then odd specified revisions must be matched exactly, whereas even specified revisions will also match the next odd revision, likewise for powers of 4, 8 and so forth. To correctly do inexact matching we'd need to re-organize the table of CPU specs to include a mask showing what PVR range the spec is compatible with (similar to the cputable code in the Linux kernel). For now, just remove the bogosity by only permitting exact PVR matches. That at least makes the matching simple and consistent. If we need inexact matching we can add the necessary per-subfamily masks later. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- target-ppc/translate_init.c | 38 +++++++------------------------------- 1 files changed, 7 insertions(+), 31 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index ca0d852..73b49cf 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -10043,40 +10043,16 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr) { - const ppc_def_t *ret; - uint32_t pvr_rev; - int i, best, match, best_match, max; + int i; - ret = NULL; - max = ARRAY_SIZE(ppc_defs); - best = -1; - pvr_rev = pvr & 0xFFFF; - /* We want all specified bits to match */ - best_match = 32 - ctz32(pvr_rev); - for (i = 0; i < max; i++) { - /* We check that the 16 higher bits are the same to ensure the CPU - * model will be the choosen one. - */ - if (((pvr ^ ppc_defs[i].pvr) >> 16) == 0) { - /* We want as much as possible of the low-level 16 bits - * to be the same but we allow inexact matches. - */ - match = clz32(pvr_rev ^ (ppc_defs[i].pvr & 0xFFFF)); - /* We check '>=' instead of '>' because the PPC_defs table - * is ordered by increasing revision. - * Then, we will match the higher revision compatible - * with the requested PVR - */ - if (match >= best_match) { - best = i; - best_match = match; - } + for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) { + /* If we have an exact match, we're done */ + if (pvr == ppc_defs[i].pvr) { + return &ppc_defs[i]; } } - if (best != -1) - ret = &ppc_defs[best]; - return ret; + return NULL; } #include