From patchwork Mon May 23 20:28:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 97050 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 EE2FDB6FBA for ; Tue, 24 May 2011 06:35:17 +1000 (EST) Received: from localhost ([::1]:50267 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObqN-0005ad-B4 for incoming@patchwork.ozlabs.org; Mon, 23 May 2011 16:35:15 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42900) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObkm-0005W9-Cu for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QObkl-0008Of-9l for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:28 -0400 Received: from mail-gx0-f173.google.com ([209.85.161.173]:34382) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObkl-0008Gg-7G for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:27 -0400 Received: by mail-gx0-f173.google.com with SMTP id 26so2727982gxk.4 for ; Mon, 23 May 2011 13:29:27 -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=mGJefZlnueIQkgIUjUleDq5Q2uMX7j0uk3woUflcpnQ=; b=eBqvJIrcCCLqiv/QFhz4K1F+yquWcSXwCEipMlRVnV9gJlBb2P/dCS/MOWQXBNp6Gi +d4aklxNiQaLrmMvU3dI4bhQGQU9f016pD8rIc6cS3Vdg0+qOBB7fbOQo0FY0G8/1Gxo zqWCvQV4npoVh2Z8EtkMthPIxevplV8f8dXrg= 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=KmBpvJAKo88mP/KFZ0l/BeOrC/SoZxFGTBdRsMlmtK/7rdvmlMH5piFvlzixu0Ymw8 53TDx1fzaB1bGg+3m4bVG0+kQWYy4j4U27cPMmJf2ylNeDAKGuLhaR/nsXB/sODp7a9l 9+jUWDOfFSSu5yE5+MMQHTCARG96SeVLUHtr4= Received: by 10.90.156.12 with SMTP id d12mr3476660age.46.1306182566892; Mon, 23 May 2011 13:29:26 -0700 (PDT) Received: from localhost.localdomain (c-71-227-161-214.hsd1.wa.comcast.net [71.227.161.214]) by mx.google.com with ESMTPS id e9sm5033668ann.24.2011.05.23.13.29.25 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 May 2011 13:29:26 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 23 May 2011 13:28:42 -0700 Message-Id: <1306182526-12081-23-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1306182526-12081-1-git-send-email-rth@twiddle.net> References: <1306182526-12081-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.161.173 Subject: [Qemu-devel] [PATCH 22/26] 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 a1f92ab..030ed17 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -320,6 +320,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 */