From patchwork Mon May 23 20:28:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 97038 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 950A7B6FBA for ; Tue, 24 May 2011 06:31:57 +1000 (EST) Received: from localhost ([::1]:55785 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObn9-00083q-5O for incoming@patchwork.ozlabs.org; Mon, 23 May 2011 16:31:55 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42654) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObkP-0004lw-CI for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QObkO-0008J1-2k for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:05 -0400 Received: from mail-yw0-f45.google.com ([209.85.213.45]:33315) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QObkN-0008Iw-VE for qemu-devel@nongnu.org; Mon, 23 May 2011 16:29:04 -0400 Received: by ywl41 with SMTP id 41so2717843ywl.4 for ; Mon, 23 May 2011 13:29:03 -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=51PCyTE2EkGKV0SAo2/A3suvbcfFDT/ZjzKL4xq/M7U=; b=D5mgJPPO/NIkjVEjw96LpCdDkCq6xv5uCqtJUfhgzrtwUmGrwSWIu8TkFAhOUBDidb 4ZqbII23zFiYagv9S/Y9+a/KOQJHOcJfqILF31CwApNWTKCCBZJU17Ox9yvChHP/YhvS FU87zofs1tR80NRpvhlA8R6HM3klDdfz9PdeQ= 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=PUUko8XImgaf/df/usIFGeL49Eaat98Xssw9ODIKbJPDOiw1SHDAzNpLzm7Dx+rM4l z1PtioUCl2sKYufDxHTJwVUygjwpqCMLCEocdZGxjXneaJkCAr9m/GjVWgBIZZRreRzo G//8nGW2ruEjpGJvTiKzQD7hmpxR9Gip1+uck= Received: by 10.101.99.18 with SMTP id b18mr4706115anm.120.1306182543436; Mon, 23 May 2011 13:29:03 -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.00 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 May 2011 13:29:01 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 23 May 2011 13:28:25 -0700 Message-Id: <1306182526-12081-6-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.213.45 Subject: [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns. 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 All of the "raw" memory accesses should be "phys" instead. Fix some confusion about argument ordering of the store routines. Fix the implementation of store-conditional. Delete the "alt-mode" helpers. Because we only implement two mmu modes, let /a imply user-mode unconditionally. Leave some combinations of virt access without permission checks as unimplemented. There are too many hoops through which to jump, and these insns will not be needed in the emulation palcode. Signed-off-by: Richard Henderson --- target-alpha/helper.h | 26 +++----- target-alpha/op_helper.c | 147 +++++++++++----------------------------------- target-alpha/translate.c | 75 +++++++----------------- 3 files changed, 65 insertions(+), 183 deletions(-) diff --git a/target-alpha/helper.h b/target-alpha/helper.h index ccf6a2a..f4f693a 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -104,23 +104,15 @@ DEF_HELPER_0(hw_rei, void) DEF_HELPER_1(hw_ret, void, i64) DEF_HELPER_2(mfpr, i64, int, i64) DEF_HELPER_2(mtpr, void, int, i64) -DEF_HELPER_0(set_alt_mode, void) -DEF_HELPER_0(restore_mode, void) - -DEF_HELPER_1(ld_virt_to_phys, i64, i64) -DEF_HELPER_1(st_virt_to_phys, i64, i64) -DEF_HELPER_2(ldl_raw, void, i64, i64) -DEF_HELPER_2(ldq_raw, void, i64, i64) -DEF_HELPER_2(ldl_l_raw, void, i64, i64) -DEF_HELPER_2(ldq_l_raw, void, i64, i64) -DEF_HELPER_2(ldl_kernel, void, i64, i64) -DEF_HELPER_2(ldq_kernel, void, i64, i64) -DEF_HELPER_2(ldl_data, void, i64, i64) -DEF_HELPER_2(ldq_data, void, i64, i64) -DEF_HELPER_2(stl_raw, void, i64, i64) -DEF_HELPER_2(stq_raw, void, i64, i64) -DEF_HELPER_2(stl_c_raw, i64, i64, i64) -DEF_HELPER_2(stq_c_raw, i64, i64, i64) + +DEF_HELPER_1(ldl_phys, i64, i64) +DEF_HELPER_1(ldq_phys, i64, i64) +DEF_HELPER_1(ldl_l_phys, i64, i64) +DEF_HELPER_1(ldq_l_phys, i64, i64) +DEF_HELPER_2(stl_phys, void, i64, i64) +DEF_HELPER_2(stq_phys, void, i64, i64) +DEF_HELPER_2(stl_c_phys, i64, i64, i64) +DEF_HELPER_2(stq_c_phys, i64, i64, i64) #endif #include "def-helper.h" diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index 4ccb10b..a90c7a6 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -1188,150 +1188,71 @@ void helper_mtpr (int iprn, uint64_t val) { cpu_alpha_mtpr(env, iprn, val, NULL); } - -void helper_set_alt_mode (void) -{ - env->saved_mode = env->ps & 0xC; - env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC); -} - -void helper_restore_mode (void) -{ - env->ps = (env->ps & ~0xC) | env->saved_mode; -} - #endif /*****************************************************************************/ /* Softmmu support */ #if !defined (CONFIG_USER_ONLY) - -/* XXX: the two following helpers are pure hacks. - * Hopefully, we emulate the PALcode, then we should never see - * HW_LD / HW_ST instructions. - */ -uint64_t helper_ld_virt_to_phys (uint64_t virtaddr) -{ - uint64_t tlb_addr, physaddr; - int index, mmu_idx; - void *retaddr; - - mmu_idx = cpu_mmu_index(env); - index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - redo: - tlb_addr = env->tlb_table[mmu_idx][index].addr_read; - if ((virtaddr & TARGET_PAGE_MASK) == - (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; - } else { - /* the page is not in the TLB : fill it */ - retaddr = GETPC(); - tlb_fill(virtaddr, 0, mmu_idx, retaddr); - goto redo; - } - return physaddr; -} - -uint64_t helper_st_virt_to_phys (uint64_t virtaddr) -{ - uint64_t tlb_addr, physaddr; - int index, mmu_idx; - void *retaddr; - - mmu_idx = cpu_mmu_index(env); - index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - redo: - tlb_addr = env->tlb_table[mmu_idx][index].addr_write; - if ((virtaddr & TARGET_PAGE_MASK) == - (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; - } else { - /* the page is not in the TLB : fill it */ - retaddr = GETPC(); - tlb_fill(virtaddr, 1, mmu_idx, retaddr); - goto redo; - } - return physaddr; -} - -void helper_ldl_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldl_phys(uint64_t p) { - ldl_raw(t1, t0); + return (int32_t)ldl_phys(p); } -void helper_ldq_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldq_phys(uint64_t p) { - ldq_raw(t1, t0); + return ldq_phys(p); } -void helper_ldl_l_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldl_l_phys(uint64_t p) { - env->lock = t1; - ldl_raw(t1, t0); + env->lock_addr = p; + return env->lock_value = (int32_t)ldl_phys(p); } -void helper_ldq_l_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldq_l_phys(uint64_t p) { - env->lock = t1; - ldl_raw(t1, t0); + env->lock_addr = p; + return env->lock_value = ldl_phys(p); } -void helper_ldl_kernel(uint64_t t0, uint64_t t1) +void helper_stl_phys(uint64_t p, uint64_t v) { - ldl_kernel(t1, t0); + stl_phys(p, v); } -void helper_ldq_kernel(uint64_t t0, uint64_t t1) +void helper_stq_phys(uint64_t p, uint64_t v) { - ldq_kernel(t1, t0); + stq_phys(p, v); } -void helper_ldl_data(uint64_t t0, uint64_t t1) +uint64_t helper_stl_c_phys(uint64_t p, uint64_t v) { - ldl_data(t1, t0); -} + uint64_t ret = 0; -void helper_ldq_data(uint64_t t0, uint64_t t1) -{ - ldq_data(t1, t0); -} - -void helper_stl_raw(uint64_t t0, uint64_t t1) -{ - stl_raw(t1, t0); -} - -void helper_stq_raw(uint64_t t0, uint64_t t1) -{ - stq_raw(t1, t0); -} - -uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1) -{ - uint64_t ret; - - if (t1 == env->lock) { - stl_raw(t1, t0); - ret = 0; - } else - ret = 1; - - env->lock = 1; + if (p == env->lock_addr) { + int32_t old = ldl_phys(p); + if (old == (int32_t)env->lock_value) { + stl_phys(p, v); + ret = 1; + } + } + env->lock_addr = -1; return ret; } -uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1) +uint64_t helper_stq_c_phys(uint64_t p, uint64_t v) { - uint64_t ret; + uint64_t ret = 0; - if (t1 == env->lock) { - stq_raw(t1, t0); - ret = 0; - } else - ret = 1; - - env->lock = 1; + if (p == env->lock_addr) { + uint64_t old = ldq_phys(p); + if (old == env->lock_value) { + stq_phys(p, v); + ret = 1; + } + } + env->lock_addr = -1; return ret; } diff --git a/target-alpha/translate.c b/target-alpha/translate.c index c9fd16f..73c19d9 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -2616,27 +2616,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access (hw_ldl/p) */ - gen_helper_ldl_raw(cpu_ir[ra], addr); + gen_helper_ldl_phys(cpu_ir[ra], addr); break; case 0x1: /* Quadword physical access (hw_ldq/p) */ - gen_helper_ldq_raw(cpu_ir[ra], addr); + gen_helper_ldq_phys(cpu_ir[ra], addr); break; case 0x2: /* Longword physical access with lock (hw_ldl_l/p) */ - gen_helper_ldl_l_raw(cpu_ir[ra], addr); + gen_helper_ldl_l_phys(cpu_ir[ra], addr); break; case 0x3: /* Quadword physical access with lock (hw_ldq_l/p) */ - gen_helper_ldq_l_raw(cpu_ir[ra], addr); + gen_helper_ldq_l_phys(cpu_ir[ra], addr); break; case 0x4: /* Longword virtual PTE fetch (hw_ldl/v) */ - tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0); - break; + goto invalid_opc; case 0x5: /* Quadword virtual PTE fetch (hw_ldq/v) */ - tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0); + goto invalid_opc; break; case 0x6: /* Incpu_ir[ra]id */ @@ -2646,14 +2645,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) goto invalid_opc; case 0x8: /* Longword virtual access (hw_ldl) */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldl_raw(cpu_ir[ra], addr); - break; + goto invalid_opc; case 0x9: /* Quadword virtual access (hw_ldq) */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldq_raw(cpu_ir[ra], addr); - break; + goto invalid_opc; case 0xA: /* Longword virtual access with protection check (hw_ldl/w) */ tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0); @@ -2664,33 +2659,19 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0xC: /* Longword virtual access with alt access mode (hw_ldl/a)*/ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldl_raw(cpu_ir[ra], addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xD: /* Quadword virtual access with alt access mode (hw_ldq/a) */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldq_raw(cpu_ir[ra], addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xE: /* Longword virtual access with alternate access mode and - * protection checks (hw_ldl/wa) - */ - gen_helper_set_alt_mode(); - gen_helper_ldl_data(cpu_ir[ra], addr); - gen_helper_restore_mode(); + protection checks (hw_ldl/wa) */ + tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX); break; case 0xF: /* Quadword virtual access with alternate access mode and - * protection checks (hw_ldq/wa) - */ - gen_helper_set_alt_mode(); - gen_helper_ldq_data(cpu_ir[ra], addr); - gen_helper_restore_mode(); + protection checks (hw_ldq/wa) */ + tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX); break; } tcg_temp_free(addr); @@ -2940,30 +2921,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access */ - gen_helper_stl_raw(val, addr); + gen_helper_stl_phys(addr, val); break; case 0x1: /* Quadword physical access */ - gen_helper_stq_raw(val, addr); + gen_helper_stq_phys(addr, val); break; case 0x2: /* Longword physical access with lock */ - gen_helper_stl_c_raw(val, val, addr); + gen_helper_stl_c_phys(val, addr, val); break; case 0x3: /* Quadword physical access with lock */ - gen_helper_stq_c_raw(val, val, addr); + gen_helper_stq_c_phys(val, addr, val); break; case 0x4: /* Longword virtual access */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - break; + goto invalid_opc; case 0x5: /* Quadword virtual access */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stq_raw(val, addr); - break; + goto invalid_opc; case 0x6: /* Invalid */ goto invalid_opc; @@ -2984,18 +2961,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) goto invalid_opc; case 0xC: /* Longword virtual access with alternate access mode */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xD: /* Quadword virtual access with alternate access mode */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xE: /* Invalid */ goto invalid_opc;