From patchwork Mon May 9 21:34:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 94885 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 A7B9EB6F18 for ; Tue, 10 May 2011 07:45:53 +1000 (EST) Received: from localhost ([::1]:49770 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QJYH0-00052l-MY for incoming@patchwork.ozlabs.org; Mon, 09 May 2011 17:45:50 -0400 Received: from eggs.gnu.org ([140.186.70.92]:38548) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QJY6n-0003lj-Ta for qemu-devel@nongnu.org; Mon, 09 May 2011 17:35:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QJY6m-0006Md-SM for qemu-devel@nongnu.org; Mon, 09 May 2011 17:35:17 -0400 Received: from mail-iy0-f173.google.com ([209.85.210.173]:48729) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QJY6m-0006A3-Mc for qemu-devel@nongnu.org; Mon, 09 May 2011 17:35:16 -0400 Received: by mail-iy0-f173.google.com with SMTP id 10so5564538iym.4 for ; Mon, 09 May 2011 14:35:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:subject:date:message-id:x-mailer :in-reply-to:references; bh=bpdijW+yf/b07LzyqVEqEQ4eG/3iiuEe6UZIOvSHLKE=; b=vqRMXqGplZFuf9tPZI8XW/0ZgT3jPniw4Bx8Ar0BgPXbSaZMJIC690GWUGq58D1VAu CVdPtdxPapEdG7zQEw/85llqvq0jo66G8Nk4tPiVLCMeBFMAnZzy+5bZS2N322EjrOvT EJz3gu1xkEbtOwG7i2+0vZIjSL+qUx6moj+XU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; b=G+csfZz6ITsW/BNZ7kFiM1YvaiKLWD5OEgI/WHyM1iVCqG91aQKFBQRP05K7BnHNTZ oKzh25uM10Rypgo+Y9ISyekL+2xPXxVEcst2Wo0OWQM5SbHVgntxxX2JqbxxFO4xbtq2 uIxc4cmDo9gSB95YmfiQAm6qVnZHAULK8rNpc= Received: by 10.42.146.134 with SMTP id j6mr6624252icv.282.1304976916457; Mon, 09 May 2011 14:35:16 -0700 (PDT) Received: from localhost.localdomain (are.twiddle.net [75.101.38.216]) by mx.google.com with ESMTPS id ui7sm2549819icb.14.2011.05.09.14.35.15 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 09 May 2011 14:35:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 9 May 2011 14:34:36 -0700 Message-Id: <1304976889-29675-23-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1304976889-29675-1-git-send-email-rth@twiddle.net> References: <1304976889-29675-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.173 Subject: [Qemu-devel] [PATCH 22/35] target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode. 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 Reads the page table how PALcode would, except that the virtual page table base register is not used. Signed-off-by: Richard Henderson --- target-alpha/cpu.h | 13 +++++ target-alpha/helper.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 4 deletions(-) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index b439751..fc0cd61 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -321,6 +321,19 @@ enum { #define CPU_INTERRUPT_SMP CPU_INTERRUPT_TGT_EXT_1 #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 +/* OSF/1 Page table bits. */ +enum { + PTE_VALID = 0x0001, + PTE_FOR = 0x0002, /* used for page protection (fault on read) */ + PTE_FOW = 0x0004, /* used for page protection (fault on write) */ + PTE_FOE = 0x0008, /* used for page protection (fault on exec) */ + PTE_ASM = 0x0010, + PTE_KRE = 0x0100, + PTE_URE = 0x0200, + PTE_KWE = 0x1000, + PTE_UWE = 0x2000 +}; + /* Hardware interrupt (entInt) constants. */ enum { INT_K_IP, diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 4f706f2..96b407b 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -200,14 +200,135 @@ void swap_shadow_regs(CPUState *env) env->shadow[7] = i7; } -target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) +/* Returns the OSF/1 entMM failure indication, or -1 on success. */ +static int get_physical_address(CPUState *env, target_ulong addr, + int prot_need, int mmu_idx, + target_ulong *pphys, int *pprot) { - return -1; + target_long saddr = addr; + target_ulong phys = 0; + target_ulong L1pte, L2pte, L3pte; + target_ulong pt, index; + int prot = 0; + int ret = MM_K_ACV; + + /* Ensure that the virtual address is properly sign-extended from + the last implemented virtual address bit. */ + if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) { + goto exit; + } + + /* Translate the superpage. */ + /* ??? When we do more than emulate Unix PALcode, we'll need to + determine which superpage is actually active. */ + if (saddr < 0 && (saddr >> (TARGET_VIRT_ADDR_SPACE_BITS - 2) & 3) == 2) { + /* User-space cannot access kseg addresses. */ + if (mmu_idx != MMU_KERNEL_IDX) { + goto exit; + } + + phys = saddr & ((1ull << 40) - 1); + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + ret = -1; + goto exit; + } + + /* Interpret the page table exactly like PALcode does. */ + + pt = env->ptbr; + + /* L1 page table read. */ + index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff; + L1pte = ldq_phys(pt + index*8); + + if (unlikely((L1pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + if (unlikely((L1pte & PTE_KRE) == 0)) { + goto exit; + } + pt = L1pte >> 32 << TARGET_PAGE_BITS; + + /* L2 page table read. */ + index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff; + L2pte = ldq_phys(pt + index*8); + + if (unlikely((L2pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + if (unlikely((L2pte & PTE_KRE) == 0)) { + goto exit; + } + pt = L2pte >> 32 << TARGET_PAGE_BITS; + + /* L3 page table read. */ + index = (addr >> TARGET_PAGE_BITS) & 0x3ff; + L3pte = ldq_phys(pt + index*8); + + phys = L3pte >> 32 << TARGET_PAGE_BITS; + if (unlikely((L3pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + +#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4 +# error page bits out of date +#endif + + /* Check access violations. */ + if (L3pte & (PTE_KRE << mmu_idx)) { + prot |= PAGE_READ | PAGE_EXEC; + } + if (L3pte & (PTE_KWE << mmu_idx)) { + prot |= PAGE_WRITE; + } + if (unlikely((prot & prot_need) == 0 && prot_need)) { + goto exit; + } + + /* Check fault-on-operation violations. */ + prot &= ~(L3pte >> 1); + ret = -1; + if (unlikely((prot & prot_need) == 0)) { + ret = (prot_need & PAGE_EXEC ? MM_K_FOE : + prot_need & PAGE_WRITE ? MM_K_FOW : + prot_need & PAGE_READ ? MM_K_FOR : -1); + } + + exit: + *pphys = phys; + *pprot = prot; + return ret; } -int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +{ + target_ulong phys; + int prot, fail; + + fail = get_physical_address(env, addr, 0, 0, &phys, &prot); + return (fail >= 0 ? -1 : phys); +} + +int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw, + int mmu_idx, int is_softmmu) { + target_ulong phys; + int prot, fail; + + fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot); + if (unlikely(fail >= 0)) { + env->exception_index = EXCP_MMFAULT; + env->trap_arg0 = addr; + env->trap_arg1 = fail; + env->trap_arg2 = (rw == 2 ? -1 : rw); + return 1; + } + + tlb_set_page(env, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, + prot, mmu_idx, TARGET_PAGE_SIZE); return 0; } #endif /* USER_ONLY */