From patchwork Thu Apr 28 20:51:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 93313 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 4EB671007DB for ; Fri, 29 Apr 2011 06:57:34 +1000 (EST) Received: from localhost ([::1]:45470 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFYHC-0007jv-Pw for incoming@patchwork.ozlabs.org; Thu, 28 Apr 2011 16:57:30 -0400 Received: from eggs.gnu.org ([140.186.70.92]:47997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFYBj-0005YZ-AH for qemu-devel@nongnu.org; Thu, 28 Apr 2011 16:51:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QFYBi-0005fV-52 for qemu-devel@nongnu.org; Thu, 28 Apr 2011 16:51:51 -0400 Received: from mail-px0-f179.google.com ([209.85.212.179]:45275) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFYBh-0005Xx-Ux for qemu-devel@nongnu.org; Thu, 28 Apr 2011 16:51:50 -0400 Received: by mail-px0-f179.google.com with SMTP id 2so298075pxi.10 for ; Thu, 28 Apr 2011 13:51:49 -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=UC4UU3lOD677KHnqy0QN5ewFBnvvtBnKiPA/GcvYJz0=; b=ndnJp0t0g5j9K7kSLXOmEK5IkuFQUB8eeNDGRBSCYnOLaXV5kVYGEL/wC5OAR91T16 vBcOoWiAtiGAk6gsczCcHg3nss1t/rwOOpdcSLGggLNqMZw1M1h0eQZAZvrPPA1g0YlA vAyZfVWYqNquOIV4PepOkxoEurZtVAh6aJbpE= 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=jIRHPoOdhBofWsq+bh6USCmw5MQ8/7v9B8opubDLhi0XjbpaTodgSOHDs4TsX5ZlXW qyGG7idaSIoNrRb37FTDa6QX3kWIeE5660oJfNwHpd+ujgcKJDNV0cr5k8CLGkbWq9t1 PMpM0PGZuHTBX3qLtDqjKlItZqkpsojZYBYXw= Received: by 10.143.178.10 with SMTP id f10mr1421880wfp.108.1304023909468; Thu, 28 Apr 2011 13:51:49 -0700 (PDT) Received: from localhost.localdomain (are.twiddle.net [75.101.38.216]) by mx.google.com with ESMTPS id z10sm2266797wfj.12.2011.04.28.13.51.48 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Apr 2011 13:51:49 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 28 Apr 2011 13:51:05 -0700 Message-Id: <1304023875-25040-24-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1304023875-25040-1-git-send-email-rth@twiddle.net> References: <1304023875-25040-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.212.179 Subject: [Qemu-devel] [PATCH 23/33] 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 | 12 +++++ target-alpha/helper.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 137 insertions(+), 4 deletions(-) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index c1ccf01..bb76edb 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -316,6 +316,18 @@ enum { EXCP_STQ_C, }; +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 */