From patchwork Thu Jul 21 15:16:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tsuneo Saito X-Patchwork-Id: 106094 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 E04DBB6F77 for ; Fri, 22 Jul 2011 02:22:41 +1000 (EST) Received: from localhost ([::1]:58811 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qjv33-0002Id-2y for incoming@patchwork.ozlabs.org; Thu, 21 Jul 2011 11:20:25 -0400 Received: from eggs.gnu.org ([140.186.70.92]:51930) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qjv2a-00019R-MK for qemu-devel@nongnu.org; Thu, 21 Jul 2011 11:19:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qjuzx-00032a-7o for qemu-devel@nongnu.org; Thu, 21 Jul 2011 11:17:20 -0400 Received: from mail-pz0-f43.google.com ([209.85.210.43]:45573) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qjuzx-00032F-30 for qemu-devel@nongnu.org; Thu, 21 Jul 2011 11:17:13 -0400 Received: by mail-pz0-f43.google.com with SMTP id 1so2207122pzk.30 for ; Thu, 21 Jul 2011 08:17:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=PdAWI/IULkhurTVSkX9YvgdoI8PIloqs3GYm6v2emnw=; b=ji+hQGh5USCa+ZNfKj2mmSwMRZyBo5nkpTNwf8BjwLzUqi5WiVEXuoa9BNxjYzF0lt GqLQbKK82u0iGCu/eHuOzsA2hr/nwhuh4sq2EQ6EWRyfMp9SriTj0hO2uT7KY5h0qqlD fMCgTo85PEPi698oqiKjPG2QTVtLC2qwGBoyg= Received: by 10.68.29.74 with SMTP id i10mr444894pbh.69.1311261432642; Thu, 21 Jul 2011 08:17:12 -0700 (PDT) Received: from localhost.localdomain (tetkyo149119.tkyo.te.ftth2.ppp.infoweb.ne.jp [202.219.195.119]) by mx.google.com with ESMTPS id g4sm948229pbj.73.2011.07.21.08.17.11 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 21 Jul 2011 08:17:12 -0700 (PDT) From: Tsuneo Saito To: qemu-devel@nongnu.org Date: Fri, 22 Jul 2011 00:16:28 +0900 Message-Id: <1311261393-47400-3-git-send-email-tsnsaito@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1311261393-47400-1-git-send-email-tsnsaito@gmail.com> References: <1311261393-47400-1-git-send-email-tsnsaito@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.43 Cc: Tsuneo Saito Subject: [Qemu-devel] [PATCH 2/7] SPARC64: SFSR cleanup and fix 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 Add macros for SFSR fields and use macros instead of magic numbers. Also fix the update of the register fields on MMU faults. Signed-off-by: Tsuneo Saito --- target-sparc/cpu.h | 22 ++++++++++++++++++++ target-sparc/helper.c | 52 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index b2160e9..348858e 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -309,6 +309,28 @@ enum { #define TTE_PGSIZE(tte) (((tte) >> 61) & 3ULL) #define TTE_PA(tte) ((tte) & 0x1ffffffe000ULL) +#define SFSR_NF_BIT (1ULL << 24) /* JPS1 NoFault */ +#define SFSR_TM_BIT (1ULL << 15) /* JPS1 TLB Miss */ +#define SFSR_FT_VA_IMMU_BIT (1ULL << 13) /* USIIi VA out of range (IMMU) */ +#define SFSR_FT_VA_DMMU_BIT (1ULL << 12) /* USIIi VA out of range (DMMU) */ +#define SFSR_FT_NFO_BIT (1ULL << 11) /* NFO page access */ +#define SFSR_FT_ILL_BIT (1ULL << 10) /* illegal LDA/STA ASI */ +#define SFSR_FT_ATOMIC_BIT (1ULL << 9) /* atomic op on noncacheable area */ +#define SFSR_FT_NF_E_BIT (1ULL << 8) /* NF access on side effect area */ +#define SFSR_FT_PRIV_BIT (1ULL << 7) /* privilege violation */ +#define SFSR_PR_BIT (1ULL << 3) /* privilege mode */ +#define SFSR_WRITE_BIT (1ULL << 2) /* write access mode */ +#define SFSR_OW_BIT (1ULL << 1) /* status overwritten */ +#define SFSR_VALID_BIT (1ULL << 0) /* status valid */ + +#define SFSR_ASI_SHIFT 16 /* 23:16 ASI value */ +#define SFSR_ASI_MASK (0xffULL << SFSR_ASI_SHIFT) +#define SFSR_CT_PRIMARY (0ULL << 4) /* 5:4 context type */ +#define SFSR_CT_SECONDARY (1ULL << 4) +#define SFSR_CT_NUCLEUS (2ULL << 4) +#define SFSR_CT_NOTRANS (3ULL << 4) +#define SFSR_CT_MASK (3ULL << 4) + typedef struct SparcTLBEntry { uint64_t tag; uint64_t tte; diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 0a4cfc5..f9b7fe2 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -413,6 +413,7 @@ static int get_physical_address_data(CPUState *env, { unsigned int i; uint64_t context; + uint64_t sfsr = 0; int is_user = (mmu_idx == MMU_USER_IDX || mmu_idx == MMU_USER_SECONDARY_IDX); @@ -427,26 +428,32 @@ static int get_physical_address_data(CPUState *env, case MMU_USER_IDX: case MMU_KERNEL_IDX: context = env->dmmu.mmu_primary_context & 0x1fff; + sfsr |= SFSR_CT_PRIMARY; break; case MMU_USER_SECONDARY_IDX: case MMU_KERNEL_SECONDARY_IDX: context = env->dmmu.mmu_secondary_context & 0x1fff; + sfsr |= SFSR_CT_SECONDARY; break; case MMU_NUCLEUS_IDX: + sfsr |= SFSR_CT_NUCLEUS; + /* FALLTHRU */ default: context = 0; break; } + if (rw == 1) { + sfsr |= SFSR_WRITE_BIT; + } + for (i = 0; i < 64; i++) { // ctx match, vaddr match, valid? if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) { - uint8_t fault_type = 0; - // access ok? if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) { - fault_type |= 1; /* privilege violation */ + sfsr |= SFSR_FT_PRIV_BIT; /* privilege violation */ env->exception_index = TT_DFAULT; DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64 @@ -469,13 +476,17 @@ static int get_physical_address_data(CPUState *env, return 0; } - if (env->dmmu.sfsr & 1) /* Fault status register */ - env->dmmu.sfsr = 2; /* overflow (not read before - another fault) */ + if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */ + sfsr |= SFSR_OW_BIT; /* overflow (not read before + another fault) */ + } - env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1; + if (env->pstate & PS_PRIV) { + sfsr |= SFSR_PR_BIT; + } - env->dmmu.sfsr |= (fault_type << 7); + /* FIXME: ASI field in SFSR must be set */ + env->dmmu.sfsr = sfsr | SFSR_VALID_BIT; env->dmmu.sfar = address; /* Fault address register */ @@ -488,6 +499,11 @@ static int get_physical_address_data(CPUState *env, DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n", address, context); + /* + * On MMU misses: + * - UltraSPARC IIi: SFSR and SFAR unmodified + * - JPS1: SFAR updated and some fields of SFSR updated + */ env->dmmu.tag_access = (address & ~0x1fffULL) | context; env->exception_index = TT_DMISS; return 1; @@ -524,10 +540,22 @@ static int get_physical_address_code(CPUState *env, address, context, physical)) { // access ok? if (TTE_IS_PRIV(env->itlb[i].tte) && is_user) { - if (env->immu.sfsr) /* Fault status register */ - env->immu.sfsr = 2; /* overflow (not read before - another fault) */ - env->immu.sfsr |= (is_user << 3) | 1; + /* Fault status register */ + if (env->immu.sfsr & SFSR_VALID_BIT) { + env->immu.sfsr = SFSR_OW_BIT; /* overflow (not read before + another fault) */ + } else { + env->immu.sfsr = 0; + } + if (env->pstate & PS_PRIV) { + env->immu.sfsr |= SFSR_PR_BIT; + } + if (env->tl > 0) { + env->immu.sfsr |= SFSR_CT_NUCLEUS; + } + + /* FIXME: ASI field in SFSR must be set */ + env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT; env->exception_index = TT_TFAULT; env->immu.tag_access = (address & ~0x1fffULL) | context;