From patchwork Tue May 14 20:44:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943745 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7428292A for ; Tue, 14 May 2019 21:04:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53005287CE for ; Tue, 14 May 2019 21:04:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 43B6A2886C; Tue, 14 May 2019 21:04:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8131D287CE for ; Tue, 14 May 2019 21:04:16 +0000 (UTC) Received: from localhost ([127.0.0.1]:54130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeat-0003rW-Sv for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:04:15 -0400 Received: from eggs.gnu.org ([209.51.188.92]:38994) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV4-0007lR-RW for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIU-0007CE-NK for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:23 -0400 Received: from mail-lf1-x143.google.com ([2a00:1450:4864:20::143]:35270) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIT-00076T-Gm for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:14 -0400 Received: by mail-lf1-x143.google.com with SMTP id c17so261258lfi.2 for ; Tue, 14 May 2019 13:45:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IkhMNMK+Km3YXVzPE7/k37mvtEbVmKcfhC7w5xerFoU=; b=hoyk/kO4WdlEEGBdC2efMClje89uRLZpTuT557KXH54GCdPu0jGzwNwmDs1P03IdN8 +UZgoTnAwRF7aD+CiGGwfZ76szH8iP/rn+jv2C2KzfF09aQLvxuy2pn+MHwGsq191PeE QQznMdwWEOrnjN2TLARcpGrSrlkC4Lwx+xXWVItBHrejzIex+i3AoTlPbolc8prD7dBa Pkt5NCgy9jSJVfqwvMLQoejB8eBKuZmp8JVmsv/CBJtm2mBLjhhmm+aG82f/XC60O9ei br9eH9ZmjNckWcZRbtnoDZMDu+QkGS3769z9EZfyT7IMnDvO1G8n5l48ACb2CLS942V0 EZow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IkhMNMK+Km3YXVzPE7/k37mvtEbVmKcfhC7w5xerFoU=; b=J2YBpBFTL/FK7MJbnNBLvj0kjLBfY4nNcG0ARxJK6D15+ziK3CGJ3MUBsPwb1IWapi I4DePkPvpL6iPWB0twJcXZCp08/oDD42opXoiPqXTn49CgRKP5vRxzHil+DDzU8O3uIY uizTMy7xhb7MSRlbAfW4VPv8rBcc2RmtHdjM/f9EDmVZ0ghnYtS3KJdpWsAyHCBfNVer egQwslZGITFFC1aDZeDcNCFMJ0lLb8dysmMCWcjbEXWBez95sYUn3lkezvlPREQLbJlC 1DyIgVsqWRa5IxaKBQNs3wdVxct0d35JHZGvzx9IjvhHtfsuNocSdH3GYOwQiN28f3Rz 0GrA== X-Gm-Message-State: APjAAAUpc9/XWf9Squi6wduM4n1ZQuKKoXg8+5fSziEsrdoo71qhEAZt lOOD7CmcHRjjVk0wF/k1gOdXkSEPwao= X-Google-Smtp-Source: APXvYqxAbZNtI8Dgjg5I3ZCG9bzZfY/9hlV+IrW+ZswQ6db8g6mXYUqyp3eKvzKf0wkbUkQm8ke3Ww== X-Received: by 2002:ac2:510b:: with SMTP id q11mr16237325lfb.11.1557866710260; Tue, 14 May 2019 13:45:10 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:09 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:39 -0700 Message-Id: <20190514204447.17486-2-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::143 Subject: [Qemu-devel] [PATCH 1/9] target/xtensa: get rid of centralized SR properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP SR numbers are not unique: different Xtensa options may reuse SR number for different purposes. Introduce generic rsr/wsr functions and xsr template and use them instead of centralized SR access functions. Change prototypes of specific rsr/wsr functions to match XtensaOpcodeOp and use them instead of centralized SR access functions. Put xtensa option that introduces SR into the second opcode description parameter and use it to test for rsr/wsr/xsr opcode validity. Extract SR and UR names for the xtensa_cpu_dump_state from libisa. Merge SRs and URs in the dump. Register names of used SR/UR in init_libisa and use these names for TCG globals referencing these SR/UR. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 1 + target/xtensa/helper.c | 1 + target/xtensa/translate.c | 2503 +++++++++++++++++++++++++++------------------ 3 files changed, 1492 insertions(+), 1013 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 5d23e1345be5..539033fccb61 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -589,6 +589,7 @@ void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, #define XTENSA_DEFAULT_CPU_NOMMU_TYPE \ XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_NOMMU_MODEL) +void xtensa_collect_sr_names(const XtensaConfig *config); void xtensa_translate_init(void); void **xtensa_get_regfile_by_name(const char *name); void xtensa_breakpoint_handler(CPUState *cs); diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index 5f37f378a311..ed0108a81209 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -141,6 +141,7 @@ static void init_libisa(XtensaConfig *config) } #endif } + xtensa_collect_sr_names(config); } static void xtensa_finalize_config(XtensaConfig *config) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 301c8e31613c..100d6e126590 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -92,128 +92,40 @@ static GHashTable *xtensa_regfile_table; #include "exec/gen-icount.h" -typedef struct XtensaReg { - const char *name; - uint64_t opt_bits; - enum { - SR_R = 1, - SR_W = 2, - SR_X = 4, - SR_RW = 3, - SR_RWX = 7, - } access; -} XtensaReg; - -#define XTENSA_REG_ACCESS(regname, opt, acc) { \ - .name = (regname), \ - .opt_bits = XTENSA_OPTION_BIT(opt), \ - .access = (acc), \ - } +static char *sr_name[256]; +static char *ur_name[256]; -#define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX) +void xtensa_collect_sr_names(const XtensaConfig *config) +{ + xtensa_isa isa = config->isa; + int n = xtensa_isa_num_sysregs(isa); + int i; -#define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \ - .name = (regname), \ - .opt_bits = (opt), \ - .access = (acc), \ + for (i = 0; i < n; ++i) { + int sr = xtensa_sysreg_number(isa, i); + + if (sr >= 0 && sr < 256) { + const char *name = xtensa_sysreg_name(isa, i); + char **pname = + (xtensa_sysreg_is_user(isa, i) ? ur_name : sr_name) + sr; + + if (*pname) { + if (strstr(*pname, name) == NULL) { + char *new_name = + malloc(strlen(*pname) + strlen(name) + 2); + + strcpy(new_name, *pname); + strcat(new_name, "/"); + strcat(new_name, name); + free(*pname); + *pname = new_name; + } + } else { + *pname = strdup(name); + } + } } - -#define XTENSA_REG_BITS(regname, opt) \ - XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX) - -static const XtensaReg sregnames[256] = { - [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP), - [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP), - [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP), - [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL), - [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN), - [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R), - [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE), - [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16), - [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16), - [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16), - [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16), - [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16), - [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16), - [PREFCTL] = XTENSA_REG_BITS("PREFCTL", XTENSA_OPTION_ALL), - [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER), - [WINDOW_START] = XTENSA_REG("WINDOW_START", - XTENSA_OPTION_WINDOWED_REGISTER), - [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU), - [MMID] = XTENSA_REG_BITS("MMID", XTENSA_OPTION_ALL), - [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU), - [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU), - [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU), - [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG), - [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL), - [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR), - [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL), - [DDR] = XTENSA_REG("DDR", XTENSA_OPTION_DEBUG), - [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG), - [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG), - [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG), - [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG), - [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG), - [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG), - [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R), - [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION), - [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION), - [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R), - [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION), - [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7", - XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), - [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR), - [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW), - [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W), - [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT), - [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL), - [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR), - [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION), - [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R), - [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT), - [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R), - [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG), - [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG), - [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION), - [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT), - [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1", - XTENSA_OPTION_TIMER_INTERRUPT), - [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2", - XTENSA_OPTION_TIMER_INTERRUPT), - [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR), - [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR), - [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR), - [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR), -}; - -static const XtensaReg uregnames[256] = { - [EXPSTATE] = XTENSA_REG_BITS("EXPSTATE", XTENSA_OPTION_ALL), - [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER), - [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR), - [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR), -}; +} void xtensa_translate_init(void) { @@ -283,18 +195,20 @@ void xtensa_translate_init(void) } for (i = 0; i < 256; ++i) { - if (sregnames[i].name) { + if (sr_name[i]) { cpu_SR[i] = tcg_global_mem_new_i32(cpu_env, - offsetof(CPUXtensaState, sregs[i]), - sregnames[i].name); + offsetof(CPUXtensaState, + sregs[i]), + sr_name[i]); } } for (i = 0; i < 256; ++i) { - if (uregnames[i].name) { + if (ur_name[i]) { cpu_UR[i] = tcg_global_mem_new_i32(cpu_env, - offsetof(CPUXtensaState, uregs[i]), - uregnames[i].name); + offsetof(CPUXtensaState, + uregs[i]), + ur_name[i]); } } @@ -536,313 +450,57 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond, tcg_temp_free(tmp); } -static bool check_sr(DisasContext *dc, uint32_t sr, unsigned access) -{ - if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) { - if (sregnames[sr].name) { - qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name); - } else { - qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr); - } - return false; - } else if (!(sregnames[sr].access & access)) { - static const char * const access_text[] = { - [SR_R] = "rsr", - [SR_W] = "wsr", - [SR_X] = "xsr", - }; - assert(access < ARRAY_SIZE(access_text) && access_text[access]); - qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name, - access_text[access]); - return false; - } - return true; -} - -#ifndef CONFIG_USER_ONLY -static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) -{ - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_start(); - } - gen_helper_update_ccount(cpu_env); - tcg_gen_mov_i32(d, cpu_SR[sr]); - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_end(); - } -} - -static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr) -{ - tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10); - tcg_gen_or_i32(d, d, cpu_SR[sr]); - tcg_gen_andi_i32(d, d, 0xfffffffc); -} -#endif - -static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) -{ - static void (* const rsr_handler[256])(DisasContext *dc, - TCGv_i32 d, uint32_t sr) = { -#ifndef CONFIG_USER_ONLY - [CCOUNT] = gen_rsr_ccount, - [INTSET] = gen_rsr_ccount, - [PTEVADDR] = gen_rsr_ptevaddr, -#endif - }; - - if (rsr_handler[sr]) { - rsr_handler[sr](dc, d, sr); - } else { - tcg_gen_mov_i32(d, cpu_SR[sr]); - } -} - -static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s) -{ - tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f); - if (dc->sar_m32_5bit) { - tcg_gen_discard_i32(dc->sar_m32); - } - dc->sar_5bit = false; - dc->sar_m32_5bit = false; -} - -static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s) -{ - tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff); -} - -static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s) -{ - tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001); -} - -static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) -{ - tcg_gen_ext8s_i32(cpu_SR[sr], s); -} - -#ifndef CONFIG_USER_ONLY -static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_mov_i32(cpu_windowbase_next, v); -} - -static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1); -} - -static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000); -} - -static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - gen_helper_wsr_rasid(cpu_env, v); -} - -static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000); -} - -static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - gen_helper_wsr_ibreakenable(cpu_env, v); -} - -static void gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - gen_helper_wsr_memctl(cpu_env, v); -} - -static void gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f); -} - -static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - unsigned id = sr - IBREAKA; - TCGv_i32 tmp = tcg_const_i32(id); - - assert(id < dc->config->nibreak); - gen_helper_wsr_ibreaka(cpu_env, tmp, v); - tcg_temp_free(tmp); -} - -static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - unsigned id = sr - DBREAKA; - TCGv_i32 tmp = tcg_const_i32(id); - - assert(id < dc->config->ndbreak); - gen_helper_wsr_dbreaka(cpu_env, tmp, v); - tcg_temp_free(tmp); -} - -static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - unsigned id = sr - DBREAKC; - TCGv_i32 tmp = tcg_const_i32(id); - - assert(id < dc->config->ndbreak); - gen_helper_wsr_dbreakc(cpu_env, tmp, v); - tcg_temp_free(tmp); -} - -static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, 0xff); -} - -static void gen_check_interrupts(DisasContext *dc) -{ - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_start(); - } - gen_helper_check_interrupts(cpu_env); - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_end(); - } -} - -static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v) +static bool test_ill_sr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - gen_helper_intset(cpu_env, v); + return !xtensa_option_enabled(dc->config, par[1]); } -static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v) +static bool test_ill_ccompare(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - gen_helper_intclear(cpu_env, v); -} + unsigned n = par[0] - CCOMPARE; -static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_mov_i32(cpu_SR[sr], v); + return test_ill_sr(dc, arg, par) || n >= dc->config->nccompare; } -static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) +static bool test_ill_dbreak(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | - PS_UM | PS_EXCM | PS_INTLEVEL; + unsigned n = MAX_NDBREAK; - if (option_enabled(dc, XTENSA_OPTION_MMU)) { - mask |= PS_RING; - } - tcg_gen_andi_i32(cpu_SR[sr], v, mask); -} - -static void gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_start(); + if (par[0] >= DBREAKA && par[0] < DBREAKA + MAX_NDBREAK) { + n = par[0] - DBREAKA; } - gen_helper_wsr_ccount(cpu_env, v); - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_end(); + if (par[0] >= DBREAKC && par[0] < DBREAKC + MAX_NDBREAK) { + n = par[0] - DBREAKC; } + return test_ill_sr(dc, arg, par) || n >= dc->config->ndbreak; } -static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v) +static bool test_ill_ibreak(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - if (dc->icount) { - tcg_gen_mov_i32(dc->next_icount, v); - } else { - tcg_gen_mov_i32(cpu_SR[sr], v); - } -} + unsigned n = par[0] - IBREAKA; -static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ - tcg_gen_andi_i32(cpu_SR[sr], v, 0xf); + return test_ill_sr(dc, arg, par) || n >= dc->config->nibreak; } -static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) +static bool test_ill_hpi(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - uint32_t id = sr - CCOMPARE; - TCGv_i32 tmp = tcg_const_i32(id); + unsigned n = MAX_NLEVEL + 1; - assert(id < dc->config->nccompare); - tcg_gen_mov_i32(cpu_SR[sr], v); - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_start(); - } - gen_helper_update_ccompare(cpu_env, tmp); - tcg_temp_free(tmp); - if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { - gen_io_end(); + if (par[0] >= EXCSAVE1 && par[0] < EXCSAVE1 + MAX_NLEVEL) { + n = par[0] - EXCSAVE1 + 1; } -} -#else -static void gen_check_interrupts(DisasContext *dc) -{ -} -#endif - -static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) -{ - static void (* const wsr_handler[256])(DisasContext *dc, - uint32_t sr, TCGv_i32 v) = { - [SAR] = gen_wsr_sar, - [BR] = gen_wsr_br, - [LITBASE] = gen_wsr_litbase, - [ACCHI] = gen_wsr_acchi, -#ifndef CONFIG_USER_ONLY - [WINDOW_BASE] = gen_wsr_windowbase, - [WINDOW_START] = gen_wsr_windowstart, - [PTEVADDR] = gen_wsr_ptevaddr, - [RASID] = gen_wsr_rasid, - [ITLBCFG] = gen_wsr_tlbcfg, - [DTLBCFG] = gen_wsr_tlbcfg, - [IBREAKENABLE] = gen_wsr_ibreakenable, - [MEMCTL] = gen_wsr_memctl, - [ATOMCTL] = gen_wsr_atomctl, - [IBREAKA] = gen_wsr_ibreaka, - [IBREAKA + 1] = gen_wsr_ibreaka, - [DBREAKA] = gen_wsr_dbreaka, - [DBREAKA + 1] = gen_wsr_dbreaka, - [DBREAKC] = gen_wsr_dbreakc, - [DBREAKC + 1] = gen_wsr_dbreakc, - [CPENABLE] = gen_wsr_cpenable, - [INTSET] = gen_wsr_intset, - [INTCLEAR] = gen_wsr_intclear, - [INTENABLE] = gen_wsr_intenable, - [PS] = gen_wsr_ps, - [CCOUNT] = gen_wsr_ccount, - [ICOUNT] = gen_wsr_icount, - [ICOUNTLEVEL] = gen_wsr_icountlevel, - [CCOMPARE] = gen_wsr_ccompare, - [CCOMPARE + 1] = gen_wsr_ccompare, - [CCOMPARE + 2] = gen_wsr_ccompare, -#endif - }; - - if (wsr_handler[sr]) { - wsr_handler[sr](dc, sr, s); - } else { - tcg_gen_mov_i32(cpu_SR[sr], s); + if (par[0] >= EPC1 && par[0] < EPC1 + MAX_NLEVEL) { + n = par[0] - EPC1 + 1; } -} - -static void gen_wur(uint32_t ur, TCGv_i32 s) -{ - switch (ur) { - case FCR: - gen_helper_wur_fcr(cpu_env, s); - break; - - case FSR: - tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80); - break; - - default: - tcg_gen_mov_i32(cpu_UR[ur], s); - break; + if (par[0] >= EPS2 && par[0] < EPS2 + MAX_NLEVEL - 1) { + n = par[0] - EPS2 + 2; } + return test_ill_sr(dc, arg, par) || n > dc->config->nlevel; } static void gen_load_store_alignment(DisasContext *dc, int shift, @@ -925,9 +583,17 @@ static int gen_postprocess(DisasContext *dc, int slot) { uint32_t op_flags = dc->op_flags; +#ifndef CONFIG_USER_ONLY if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { - gen_check_interrupts(dc); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + gen_helper_check_interrupts(cpu_env); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_end(); + } } +#endif if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) { gen_helper_sync_windowbase(cpu_env); } @@ -1645,24 +1311,20 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags) { XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; + xtensa_isa isa = env->config->isa; int i, j; qemu_fprintf(f, "PC=%08x\n\n", env->pc); - for (i = j = 0; i < 256; ++i) { - if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) { - qemu_fprintf(f, "%12s=%08x%c", - sregnames[i].name, env->sregs[i], - (j++ % 4) == 3 ? '\n' : ' '); - } - } - - qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); + for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) { + const uint32_t *reg = + xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs; + int regno = xtensa_sysreg_number(isa, i); - for (i = j = 0; i < 256; ++i) { - if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) { - qemu_fprintf(f, "%s=%08x%c", - uregnames[i].name, env->uregs[i], + if (regno >= 0) { + qemu_fprintf(f, "%12s=%08x%c", + xtensa_sysreg_name(isa, i), + reg[regno], (j++ % 4) == 3 ? '\n' : ' '); } } @@ -2472,16 +2134,38 @@ static void translate_rsil(DisasContext *dc, const OpcodeArg arg[], tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm); } -static bool test_ill_rsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_rsr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - return !check_sr(dc, par[0], SR_R); + tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); } -static void translate_rsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + gen_helper_update_ccount(cpu_env); + tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_end(); + } +#endif +} + +static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - gen_rsr(dc, arg[0].out, par[0]); +#ifndef CONFIG_USER_ONLY + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10); + tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]); + tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc); + tcg_temp_free(tmp); +#endif } static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], @@ -2503,11 +2187,7 @@ static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], static void translate_rur(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { - if (uregnames[par[0]].name) { - tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]); - } else { - qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]); - } + tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]); } static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[], @@ -2778,52 +2458,288 @@ static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[], tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in); } -static bool test_ill_wsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - return !check_sr(dc, par[0], SR_W); + tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); } -static void translate_wsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - gen_wsr(dc, par[0], arg[0].in); + tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]); } -static void translate_wur(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - if (uregnames[par[0]].name) { - gen_wur(par[0], arg[0].in); - } else { - qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]); - } + tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in); } -static void translate_xor(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in); +#ifndef CONFIG_USER_ONLY + uint32_t id = par[0] - CCOMPARE; + TCGv_i32 tmp = tcg_const_i32(id); + + assert(id < dc->config->nccompare); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); + gen_helper_update_ccompare(cpu_env, tmp); + tcg_temp_free(tmp); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_end(); + } +#endif } -static bool test_ill_xsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - return !check_sr(dc, par[0], SR_X); +#ifndef CONFIG_USER_ONLY + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + gen_helper_wsr_ccount(cpu_env, arg[0].in); + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_end(); + } +#endif } -static void translate_xsr(DisasContext *dc, const OpcodeArg arg[], - const uint32_t par[]) +static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) { - TCGv_i32 tmp = tcg_temp_new_i32(); +#ifndef CONFIG_USER_ONLY + unsigned id = par[0] - DBREAKA; + TCGv_i32 tmp = tcg_const_i32(id); - tcg_gen_mov_i32(tmp, arg[0].in); - gen_rsr(dc, arg[0].out, par[0]); - gen_wsr(dc, par[0], tmp); + assert(id < dc->config->ndbreak); + gen_helper_wsr_dbreaka(cpu_env, tmp, arg[0].in); tcg_temp_free(tmp); +#endif } -static const XtensaOpcodeOps core_ops[] = { +static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + unsigned id = par[0] - DBREAKC; + TCGv_i32 tmp = tcg_const_i32(id); + + assert(id < dc->config->ndbreak); + gen_helper_wsr_dbreakc(cpu_env, tmp, arg[0].in); + tcg_temp_free(tmp); +#endif +} + +static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + unsigned id = par[0] - IBREAKA; + TCGv_i32 tmp = tcg_const_i32(id); + + assert(id < dc->config->nibreak); + gen_helper_wsr_ibreaka(cpu_env, tmp, arg[0].in); + tcg_temp_free(tmp); +#endif +} + +static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_wsr_ibreakenable(cpu_env, arg[0].in); +#endif +} + +static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + if (dc->icount) { + tcg_gen_mov_i32(dc->next_icount, arg[0].in); + } else { + tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); + } +#endif +} + +static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_intclear(cpu_env, arg[0].in); +#endif +} + +static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_intset(cpu_env, arg[0].in); +#endif +} + +static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_wsr_memctl(cpu_env, arg[0].in); +#endif +} + +static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | + PS_UM | PS_EXCM | PS_INTLEVEL; + + if (option_enabled(dc, XTENSA_OPTION_MMU)) { + mask |= PS_RING; + } + tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask); +#endif +} + +static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_wsr_rasid(cpu_env, arg[0].in); +#endif +} + +static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f); + if (dc->sar_m32_5bit) { + tcg_gen_discard_i32(dc->sar_m32); + } + dc->sar_5bit = false; + dc->sar_m32_5bit = false; +} + +static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in); +#endif +} + +static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, + (1 << dc->config->nareg / 4) - 1); +#endif +} + +static void translate_wur(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in); +} + +static void translate_wur_fcr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + gen_helper_wur_fcr(cpu_env, arg[0].in); +} + +static void translate_wur_fsr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80); +} + +static void translate_xor(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in); +} + +static void translate_xsr(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_mov_i32(tmp, arg[0].in); + tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); + tcg_gen_mov_i32(cpu_SR[par[0]], tmp); + tcg_temp_free(tmp); +} + +static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_mov_i32(tmp, arg[0].in); + tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); + tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]); + tcg_temp_free(tmp); +} + +static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + TCGv_i32 tmp = tcg_temp_new_i32(); + + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + + gen_helper_update_ccount(cpu_env); + tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); + gen_helper_wsr_ccount(cpu_env, arg[0].in); + tcg_gen_mov_i32(arg[0].out, tmp); + tcg_temp_free(tmp); + + if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { + gen_io_end(); + } +#endif +} + +#define gen_translate_xsr(name) \ + static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \ + const uint32_t par[]) \ +{ \ + TCGv_i32 tmp = tcg_temp_new_i32(); \ + \ + tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \ + translate_wsr_##name(dc, arg, par); \ + tcg_gen_mov_i32(arg[0].out, tmp); \ + tcg_temp_free(tmp); \ +} + +gen_translate_xsr(acchi) +gen_translate_xsr(ccompare) +gen_translate_xsr(dbreaka) +gen_translate_xsr(dbreakc) +gen_translate_xsr(ibreaka) +gen_translate_xsr(ibreakenable) +gen_translate_xsr(icount) +gen_translate_xsr(memctl) +gen_translate_xsr(ps) +gen_translate_xsr(rasid) +gen_translate_xsr(sar) +gen_translate_xsr(windowbase) +gen_translate_xsr(windowstart) + +#undef gen_translate_xsr + +static const XtensaOpcodeOps core_ops[] = { { .name = "abs", .translate = translate_abs, @@ -3766,450 +3682,653 @@ static const XtensaOpcodeOps core_ops[] = { }, { .name = "rsr.176", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){176}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.208", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){208}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.acchi", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ACCHI}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCHI, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.acclo", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ACCLO}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCLO, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.atomctl", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ATOMCTL}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ATOMCTL, + XTENSA_OPTION_ATOMCTL, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.br", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){BR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + BR, + XTENSA_OPTION_BOOLEAN, + }, }, { .name = "rsr.cacheattr", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CACHEATTR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEATTR, + XTENSA_OPTION_CACHEATTR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ccompare0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CCOMPARE}, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ccompare1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CCOMPARE + 1}, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 1, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ccompare2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CCOMPARE + 2}, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 2, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ccount", - .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CCOUNT}, + .translate = translate_rsr_ccount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CCOUNT, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "rsr.configid0", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){CONFIGID0}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.configid1", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){CONFIGID1}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.cpenable", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){CPENABLE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CPENABLE, + XTENSA_OPTION_COPROCESSOR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.dbreaka0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DBREAKA}, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.dbreaka1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DBREAKA + 1}, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.dbreakc0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DBREAKC}, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.dbreakc1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DBREAKC + 1}, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ddr", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DDR, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.debugcause", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DEBUGCAUSE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DEBUGCAUSE, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.depc", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DEPC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DEPC, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.dtlbcfg", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){DTLBCFG}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DTLBCFG, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EPC1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc3", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc4", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc5", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc6", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.epc7", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPC1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps3", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps4", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps5", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps6", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.eps7", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EPS2 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.exccause", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCCAUSE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCCAUSE, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCSAVE1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave3", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave4", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave5", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave6", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excsave7", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCSAVE1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.excvaddr", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){EXCVADDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCVADDR, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ibreaka0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){IBREAKA}, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ibreaka1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){IBREAKA + 1}, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ibreakenable", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){IBREAKENABLE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + IBREAKENABLE, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.icount", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ICOUNT}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNT, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.icountlevel", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ICOUNTLEVEL}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNTLEVEL, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.intclear", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){INTCLEAR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTCLEAR, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.intenable", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){INTENABLE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTENABLE, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.interrupt", - .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){INTSET}, + .translate = translate_rsr_ccount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTSET, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "rsr.intset", - .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){INTSET}, + .translate = translate_rsr_ccount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTSET, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "rsr.itlbcfg", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){ITLBCFG}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ITLBCFG, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.lbeg", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){LBEG}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LBEG, + XTENSA_OPTION_LOOP, + }, }, { .name = "rsr.lcount", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){LCOUNT}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LCOUNT, + XTENSA_OPTION_LOOP, + }, }, { .name = "rsr.lend", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){LEND}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LEND, + XTENSA_OPTION_LOOP, + }, }, { .name = "rsr.litbase", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){LITBASE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LITBASE, + XTENSA_OPTION_EXTENDED_L32R, + }, }, { .name = "rsr.m0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.m1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MR + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 1, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.m2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MR + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 2, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.m3", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MR + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 3, + XTENSA_OPTION_MAC16, + }, }, { .name = "rsr.memctl", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.misc0", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MISC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.misc1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MISC + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 1, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.misc2", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MISC + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 2, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.misc3", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){MISC + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 3, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.prefctl", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){PREFCTL}, }, { .name = "rsr.prid", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){PRID}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PRID, + XTENSA_OPTION_PROCESSOR_ID, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ps", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){PS}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PS, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.ptevaddr", - .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){PTEVADDR}, + .translate = translate_rsr_ptevaddr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PTEVADDR, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.rasid", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){RASID}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + RASID, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.sar", .translate = translate_rsr, - .test_ill = test_ill_rsr, .par = (const uint32_t[]){SAR}, }, { .name = "rsr.scompare1", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){SCOMPARE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + SCOMPARE1, + XTENSA_OPTION_CONDITIONAL_STORE, + }, }, { .name = "rsr.vecbase", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){VECBASE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + VECBASE, + XTENSA_OPTION_RELOCATABLE_VECTOR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.windowbase", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){WINDOW_BASE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_BASE, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsr.windowstart", .translate = translate_rsr, - .test_ill = test_ill_rsr, - .par = (const uint32_t[]){WINDOW_START}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_START, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "rsync", @@ -4374,300 +4493,425 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_wrmsk_expstate, }, { .name = "wsr.176", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){176}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.208", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){208}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.acchi", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ACCHI}, + .translate = translate_wsr_acchi, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCHI, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.acclo", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ACCLO}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCLO, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.atomctl", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ATOMCTL}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ATOMCTL, + XTENSA_OPTION_ATOMCTL, + 0x3f, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.br", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){BR}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + BR, + XTENSA_OPTION_BOOLEAN, + 0xffff, + }, }, { .name = "wsr.cacheattr", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CACHEATTR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEATTR, + XTENSA_OPTION_CACHEATTR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.ccompare0", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CCOMPARE}, + .translate = translate_wsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.ccompare1", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CCOMPARE + 1}, + .translate = translate_wsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 1, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.ccompare2", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CCOMPARE + 2}, + .translate = translate_wsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 2, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.ccount", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CCOUNT}, + .translate = translate_wsr_ccount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CCOUNT, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.configid0", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CONFIGID0}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.configid1", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CONFIGID1}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.cpenable", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){CPENABLE}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CPENABLE, + XTENSA_OPTION_COPROCESSOR, + 0xff, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.dbreaka0", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DBREAKA}, + .translate = translate_wsr_dbreaka, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.dbreaka1", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DBREAKA + 1}, + .translate = translate_wsr_dbreaka, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.dbreakc0", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DBREAKC}, + .translate = translate_wsr_dbreakc, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.dbreakc1", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DBREAKC + 1}, + .translate = translate_wsr_dbreakc, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.ddr", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DDR, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.debugcause", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DEBUGCAUSE}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.depc", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DEPC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DEPC, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.dtlbcfg", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){DTLBCFG}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DTLBCFG, + XTENSA_OPTION_MMU, + 0x01130000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc1", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EPC1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc2", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc3", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc4", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc5", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc6", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.epc7", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPC1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps2", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps3", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps4", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps5", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps6", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.eps7", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EPS2 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.exccause", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCCAUSE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCCAUSE, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave1", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCSAVE1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave2", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave3", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave4", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave5", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave6", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excsave7", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCSAVE1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.excvaddr", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){EXCVADDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCVADDR, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.ibreaka0", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){IBREAKA}, + .translate = translate_wsr_ibreaka, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.ibreaka1", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){IBREAKA + 1}, + .translate = translate_wsr_ibreaka, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.ibreakenable", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){IBREAKENABLE}, + .translate = translate_wsr_ibreakenable, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + IBREAKENABLE, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "wsr.icount", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ICOUNT}, + .translate = translate_wsr_icount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNT, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.icountlevel", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ICOUNTLEVEL}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNTLEVEL, + XTENSA_OPTION_DEBUG, + 0xf, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.intclear", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){INTCLEAR}, + .translate = translate_wsr_intclear, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTCLEAR, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0 | @@ -4675,8 +4919,11 @@ static const XtensaOpcodeOps core_ops[] = { }, { .name = "wsr.intenable", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){INTENABLE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTENABLE, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0 | @@ -4684,167 +4931,233 @@ static const XtensaOpcodeOps core_ops[] = { }, { .name = "wsr.interrupt", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){INTSET}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTSET, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0 | XTENSA_OP_CHECK_INTERRUPTS, }, { .name = "wsr.intset", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){INTSET}, + .translate = translate_wsr_intset, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTSET, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0 | XTENSA_OP_CHECK_INTERRUPTS, }, { .name = "wsr.itlbcfg", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){ITLBCFG}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ITLBCFG, + XTENSA_OPTION_MMU, + 0x01130000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.lbeg", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){LBEG}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LBEG, + XTENSA_OPTION_LOOP, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.lcount", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){LCOUNT}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LCOUNT, + XTENSA_OPTION_LOOP, + }, }, { .name = "wsr.lend", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){LEND}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LEND, + XTENSA_OPTION_LOOP, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.litbase", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){LITBASE}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LITBASE, + XTENSA_OPTION_EXTENDED_L32R, + 0xfffff001, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.m0", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.m1", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MR + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 1, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.m2", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MR + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 2, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.m3", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MR + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 3, + XTENSA_OPTION_MAC16, + }, }, { .name = "wsr.memctl", - .translate = translate_wsr, - .test_ill = test_ill_wsr, + .translate = translate_wsr_memctl, .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.misc0", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MISC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.misc1", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MISC + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 1, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.misc2", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MISC + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 2, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.misc3", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MISC + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 3, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.mmid", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){MMID}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MMID, + XTENSA_OPTION_TRACE_PORT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.prefctl", .translate = translate_wsr, - .test_ill = test_ill_wsr, .par = (const uint32_t[]){PREFCTL}, }, { .name = "wsr.prid", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){PRID}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "wsr.ps", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){PS}, + .translate = translate_wsr_ps, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PS, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1 | XTENSA_OP_CHECK_INTERRUPTS, }, { .name = "wsr.ptevaddr", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){PTEVADDR}, + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PTEVADDR, + XTENSA_OPTION_MMU, + 0xffc00000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.rasid", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){RASID}, + .translate = translate_wsr_rasid, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + RASID, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "wsr.sar", - .translate = translate_wsr, - .test_ill = test_ill_wsr, + .translate = translate_wsr_sar, .par = (const uint32_t[]){SAR}, }, { .name = "wsr.scompare1", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){SCOMPARE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + SCOMPARE1, + XTENSA_OPTION_CONDITIONAL_STORE, + }, }, { .name = "wsr.vecbase", .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){VECBASE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + VECBASE, + XTENSA_OPTION_RELOCATABLE_VECTOR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "wsr.windowbase", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){WINDOW_BASE}, + .translate = translate_wsr_windowbase, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_BASE, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1 | XTENSA_OP_SYNC_REGISTER_WINDOW, }, { .name = "wsr.windowstart", - .translate = translate_wsr, - .test_ill = test_ill_wsr, - .par = (const uint32_t[]){WINDOW_START}, + .translate = translate_wsr_windowstart, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_START, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "wur.expstate", @@ -4852,12 +5165,12 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){EXPSTATE}, }, { .name = "wur.fcr", - .translate = translate_wur, + .translate = translate_wur_fcr, .par = (const uint32_t[]){FCR}, .coprocessor = 0x1, }, { .name = "wur.fsr", - .translate = translate_wur, + .translate = translate_wur_fsr, .par = (const uint32_t[]){FSR}, .coprocessor = 0x1, }, { @@ -4873,471 +5186,635 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){BOOLEAN_XOR}, }, { .name = "xsr.176", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){176}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.208", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){208}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.acchi", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ACCHI}, + .translate = translate_xsr_acchi, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCHI, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.acclo", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ACCLO}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ACCLO, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.atomctl", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ATOMCTL}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ATOMCTL, + XTENSA_OPTION_ATOMCTL, + 0x3f, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.br", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){BR}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + BR, + XTENSA_OPTION_BOOLEAN, + 0xffff, + }, }, { .name = "xsr.cacheattr", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CACHEATTR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEATTR, + XTENSA_OPTION_CACHEATTR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.ccompare0", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CCOMPARE}, + .translate = translate_xsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.ccompare1", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CCOMPARE + 1}, + .translate = translate_xsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 1, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.ccompare2", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CCOMPARE + 2}, + .translate = translate_xsr_ccompare, + .test_ill = test_ill_ccompare, + .par = (const uint32_t[]){ + CCOMPARE + 2, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.ccount", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CCOUNT}, + .translate = translate_xsr_ccount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CCOUNT, + XTENSA_OPTION_TIMER_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.configid0", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CONFIGID0}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.configid1", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CONFIGID1}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.cpenable", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){CPENABLE}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CPENABLE, + XTENSA_OPTION_COPROCESSOR, + 0xff, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.dbreaka0", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DBREAKA}, + .translate = translate_xsr_dbreaka, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.dbreaka1", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DBREAKA + 1}, + .translate = translate_xsr_dbreaka, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.dbreakc0", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DBREAKC}, + .translate = translate_xsr_dbreakc, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.dbreakc1", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DBREAKC + 1}, + .translate = translate_xsr_dbreakc, + .test_ill = test_ill_dbreak, + .par = (const uint32_t[]){ + DBREAKC + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.ddr", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DDR, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.debugcause", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DEBUGCAUSE}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.depc", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DEPC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DEPC, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.dtlbcfg", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){DTLBCFG}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + DTLBCFG, + XTENSA_OPTION_MMU, + 0x01130000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc1", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EPC1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc2", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc3", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc4", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc5", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc6", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.epc7", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPC1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPC1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps2", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps3", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps4", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps5", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps6", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.eps7", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EPS2 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EPS2 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.exccause", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCCAUSE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCCAUSE, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave1", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCSAVE1, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave2", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 1}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 1, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave3", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 2}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 2, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave4", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 3}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 3, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave5", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 4}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 4, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave6", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 5}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 5, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excsave7", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCSAVE1 + 6}, + .test_ill = test_ill_hpi, + .par = (const uint32_t[]){ + EXCSAVE1 + 6, + XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.excvaddr", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){EXCVADDR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + EXCVADDR, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.ibreaka0", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){IBREAKA}, + .translate = translate_xsr_ibreaka, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.ibreaka1", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){IBREAKA + 1}, + .translate = translate_xsr_ibreaka, + .test_ill = test_ill_ibreak, + .par = (const uint32_t[]){ + IBREAKA + 1, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.ibreakenable", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){IBREAKENABLE}, + .translate = translate_xsr_ibreakenable, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + IBREAKENABLE, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, }, { .name = "xsr.icount", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ICOUNT}, + .translate = translate_xsr_icount, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNT, + XTENSA_OPTION_DEBUG, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.icountlevel", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ICOUNTLEVEL}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ICOUNTLEVEL, + XTENSA_OPTION_DEBUG, + 0xf, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.intclear", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){INTCLEAR}, - .op_flags = - XTENSA_OP_PRIVILEGED | - XTENSA_OP_EXIT_TB_0 | - XTENSA_OP_CHECK_INTERRUPTS, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.intenable", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){INTENABLE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + INTENABLE, + XTENSA_OPTION_INTERRUPT, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0 | XTENSA_OP_CHECK_INTERRUPTS, }, { .name = "xsr.interrupt", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){INTSET}, - .op_flags = - XTENSA_OP_PRIVILEGED | - XTENSA_OP_EXIT_TB_0 | - XTENSA_OP_CHECK_INTERRUPTS, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.intset", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){INTSET}, - .op_flags = - XTENSA_OP_PRIVILEGED | - XTENSA_OP_EXIT_TB_0 | - XTENSA_OP_CHECK_INTERRUPTS, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.itlbcfg", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){ITLBCFG}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + ITLBCFG, + XTENSA_OPTION_MMU, + 0x01130000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.lbeg", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){LBEG}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LBEG, + XTENSA_OPTION_LOOP, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.lcount", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){LCOUNT}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LCOUNT, + XTENSA_OPTION_LOOP, + }, }, { .name = "xsr.lend", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){LEND}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LEND, + XTENSA_OPTION_LOOP, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.litbase", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){LITBASE}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + LITBASE, + XTENSA_OPTION_EXTENDED_L32R, + 0xfffff001, + }, .op_flags = XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.m0", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MR}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.m1", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MR + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 1, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.m2", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MR + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 2, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.m3", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MR + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MR + 3, + XTENSA_OPTION_MAC16, + }, }, { .name = "xsr.memctl", - .translate = translate_xsr, - .test_ill = test_ill_xsr, + .translate = translate_xsr_memctl, .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.misc0", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MISC}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.misc1", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MISC + 1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 1, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.misc2", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MISC + 2}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 2, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.misc3", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){MISC + 3}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MISC + 3, + XTENSA_OPTION_MISC_SR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.prefctl", .translate = translate_xsr, - .test_ill = test_ill_xsr, .par = (const uint32_t[]){PREFCTL}, }, { .name = "xsr.prid", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){PRID}, - .op_flags = XTENSA_OP_PRIVILEGED, + .op_flags = XTENSA_OP_ILL, }, { .name = "xsr.ps", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){PS}, + .translate = translate_xsr_ps, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PS, + XTENSA_OPTION_EXCEPTION, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1 | XTENSA_OP_CHECK_INTERRUPTS, }, { .name = "xsr.ptevaddr", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){PTEVADDR}, + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + PTEVADDR, + XTENSA_OPTION_MMU, + 0xffc00000, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.rasid", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){RASID}, + .translate = translate_xsr_rasid, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + RASID, + XTENSA_OPTION_MMU, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { .name = "xsr.sar", - .translate = translate_xsr, - .test_ill = test_ill_xsr, + .translate = translate_xsr_sar, .par = (const uint32_t[]){SAR}, }, { .name = "xsr.scompare1", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){SCOMPARE1}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + SCOMPARE1, + XTENSA_OPTION_CONDITIONAL_STORE, + }, }, { .name = "xsr.vecbase", .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){VECBASE}, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + VECBASE, + XTENSA_OPTION_RELOCATABLE_VECTOR, + }, .op_flags = XTENSA_OP_PRIVILEGED, }, { .name = "xsr.windowbase", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){WINDOW_BASE}, + .translate = translate_xsr_windowbase, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_BASE, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1 | XTENSA_OP_SYNC_REGISTER_WINDOW, }, { .name = "xsr.windowstart", - .translate = translate_xsr, - .test_ill = test_ill_xsr, - .par = (const uint32_t[]){WINDOW_START}, + .translate = translate_xsr_windowstart, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + WINDOW_START, + XTENSA_OPTION_WINDOWED_REGISTER, + }, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, }; From patchwork Tue May 14 20:44:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943753 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49BC1924 for ; Tue, 14 May 2019 21:09:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 36141287CE for ; Tue, 14 May 2019 21:09:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2995F28868; Tue, 14 May 2019 21:09:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6E441287CE for ; Tue, 14 May 2019 21:09:08 +0000 (UTC) Received: from localhost ([127.0.0.1]:54240 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQefb-0007dS-Pf for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:09:07 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV6-0007lu-8f for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIU-0007C3-Lr for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:16 -0400 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]:37183) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIT-00077c-Qe for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:14 -0400 Received: by mail-lf1-x141.google.com with SMTP id q17so251535lfo.4 for ; Tue, 14 May 2019 13:45:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ycNp4Qh4WZ1+j69cmldUs9hpgiZ5r/F5FvZ4/Ss2hCM=; b=o1shyKB/PSjAxK/khrCuiBCvnQ+Q07IfIRGdM2I157kuQc/FIqb/GECI+SqOs5i34+ z6/IjVSpM7V3JIU+F7sbY0ITvbK9VkLI8KLDcmZ4h9ymb/Z+OSn0vVTK4zja9nrIvVE2 nyQ7uGyuxPwmNB205O6Xpfs6JQJICV5cZgpf+B7f0IN+02V7xulJeV4FDK9sy7lqVoSA PLwtt4hUYXyvBF7Ea6FRPp8rNYlPNwMdZKqh7pyobq/zxg2uIlObR0Azibh5zTT0oVSK uPG2v+Z6fTI8mqkwPSht+SDm6pyDjMKQk5dzrRLdgWAPVZnNwKq7oYgXLgnXW/fpR6NF 8F4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ycNp4Qh4WZ1+j69cmldUs9hpgiZ5r/F5FvZ4/Ss2hCM=; b=H31CpmbUe+2LHrWR+eZ15B0dQq50j54JJClH3u1OW6T32FCO229n59vPacDCqzNeu7 Lry7jBpFTQw6tVkdCGuJNWCJAfmgzEkP1kwjem+CtkCfLprDF2RtoPMwQd5K9NJPpS0E TyFSY/jiPl2Tg+DHZJK6sa7AN2o6a9p4wdxu5ZGdyDxfrullBHPlgqoYS1xk/315jyhC 6/9CBSrE32RWN5TPeweI/htxAU6tXYgyKKWFOIBSG9m9pOGJvrZEJHaFpQSeFZ8ePcwM uwAPonkMLzOFE69o+aX9EfG5P7smrv6GK++E9vP+tMVvAghhHDAGFfuf1RmKKoKoEdJv 9EWQ== X-Gm-Message-State: APjAAAVquDJx+5U92EdN+DU/MMh59yr00Yx125cfXAWuHMINbAh6cUIw ZimF1frsQ78wBLIlzb3PkQ8X8m68F0k= X-Google-Smtp-Source: APXvYqxJmI6GVxhxlvhdtaFr1cLuhsF4iHzYRBsPb/X0iIV+xbqS7qSzYqLDbFyI7kVbHnq3+xKTsQ== X-Received: by 2002:a19:5015:: with SMTP id e21mr18606306lfb.62.1557866712257; Tue, 14 May 2019 13:45:12 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:11 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:40 -0700 Message-Id: <20190514204447.17486-3-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::141 Subject: [Qemu-devel] [PATCH 2/9] target/xtensa: make internal MMU functions static X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Remove declarations of the internal mmu_helper functions from the cpu.h, make these functions static and shuffle them. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 19 ------ target/xtensa/mmu_helper.c | 163 ++++++++++++++++++++++++--------------------- 2 files changed, 87 insertions(+), 95 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 539033fccb61..502d41688365 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -658,17 +658,6 @@ static inline int xtensa_get_cring(const CPUXtensaState *env) } #ifndef CONFIG_USER_ONLY -uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, - bool dtlb, uint32_t way); -void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, - uint32_t *vpn, uint32_t wi, uint32_t *ei); -int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, - uint32_t *pwi, uint32_t *pei, uint8_t *pring); -void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, - xtensa_tlb_entry *entry, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); -void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, uint32_t vaddr, int is_write, int mmu_idx, uint32_t *paddr, uint32_t *page_size, unsigned *access); @@ -679,14 +668,6 @@ static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env) { return env->system_er; } - -static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, - bool dtlb, unsigned wi, unsigned ei) -{ - return dtlb ? - env->dtlb[wi] + ei : - env->itlb[wi] + ei; -} #endif static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) diff --git a/target/xtensa/mmu_helper.c b/target/xtensa/mmu_helper.c index 79a10da2310e..465cfbf61359 100644 --- a/target/xtensa/mmu_helper.c +++ b/target/xtensa/mmu_helper.c @@ -78,8 +78,8 @@ static uint32_t get_page_size(const CPUXtensaState *env, /*! * Get bit mask for the virtual address bits translated by the TLB way */ -uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, - bool dtlb, uint32_t way) +static uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, + bool dtlb, uint32_t way) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { bool varway56 = dtlb ? @@ -145,8 +145,9 @@ static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way) * Split virtual address into VPN (with index) and entry index * for the given TLB way */ -void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, - uint32_t *vpn, uint32_t wi, uint32_t *ei) +static void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, + bool dtlb, uint32_t *vpn, + uint32_t wi, uint32_t *ei) { bool varway56 = dtlb ? env->config->dtlb.varway56 : @@ -213,6 +214,14 @@ static void split_tlb_entry_spec(CPUXtensaState *env, uint32_t v, bool dtlb, } } +static xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, bool dtlb, + unsigned wi, unsigned ei) +{ + return dtlb ? + env->dtlb[wi] + ei : + env->itlb[wi] + ei; +} + static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env, uint32_t v, bool dtlb, uint32_t *pwi) { @@ -227,65 +236,10 @@ static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env, return xtensa_tlb_get_entry(env, dtlb, wi, ei); } -uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) -{ - if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { - uint32_t wi; - const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); - return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid; - } else { - return v & REGION_PAGE_MASK; - } -} - -uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) -{ - const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, NULL); - return entry->paddr | entry->attr; -} - -void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) -{ - if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { - uint32_t wi; - xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); - if (entry->variable && entry->asid) { - tlb_flush_page(CPU(xtensa_env_get_cpu(env)), entry->vaddr); - entry->asid = 0; - } - } -} - -uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) -{ - if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { - uint32_t wi; - uint32_t ei; - uint8_t ring; - int res = xtensa_tlb_lookup(env, v, dtlb, &wi, &ei, &ring); - - switch (res) { - case 0: - if (ring >= xtensa_get_ring(env)) { - return (v & 0xfffff000) | wi | (dtlb ? 0x10 : 0x8); - } - break; - - case INST_TLB_MULTI_HIT_CAUSE: - case LOAD_STORE_TLB_MULTI_HIT_CAUSE: - HELPER(exception_cause_vaddr)(env, env->pc, res, v); - break; - } - return 0; - } else { - return (v & REGION_PAGE_MASK) | 0x1; - } -} - -void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, - xtensa_tlb_entry *entry, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, - uint32_t pte) +static void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, + xtensa_tlb_entry *entry, bool dtlb, + unsigned wi, unsigned ei, uint32_t vpn, + uint32_t pte) { entry->vaddr = vpn; entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi); @@ -293,8 +247,9 @@ void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, entry->attr = pte & 0xf; } -void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte) +static void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, + unsigned wi, unsigned ei, + uint32_t vpn, uint32_t pte) { XtensaCPU *cpu = xtensa_env_get_cpu(env); CPUState *cs = CPU(cpu); @@ -322,15 +277,6 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, } } -void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb) -{ - uint32_t vpn; - uint32_t wi; - uint32_t ei; - split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei); - xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, p); -} - hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { XtensaCPU *cpu = XTENSA_CPU(cs); @@ -462,8 +408,9 @@ static unsigned get_ring(const CPUXtensaState *env, uint8_t asid) * \param pring: [out] access ring * \return 0 if ok, exception cause code otherwise */ -int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, - uint32_t *pwi, uint32_t *pei, uint8_t *pring) +static int xtensa_tlb_lookup(const CPUXtensaState *env, + uint32_t addr, bool dtlb, + uint32_t *pwi, uint32_t *pei, uint8_t *pring) { const xtensa_tlb *tlb = dtlb ? &env->config->dtlb : &env->config->itlb; @@ -495,6 +442,70 @@ int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, (dtlb ? LOAD_STORE_TLB_MISS_CAUSE : INST_TLB_MISS_CAUSE); } +uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { + uint32_t wi; + const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); + return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid; + } else { + return v & REGION_PAGE_MASK; + } +} + +uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) +{ + const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, NULL); + return entry->paddr | entry->attr; +} + +void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { + uint32_t wi; + xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi); + if (entry->variable && entry->asid) { + tlb_flush_page(CPU(xtensa_env_get_cpu(env)), entry->vaddr); + entry->asid = 0; + } + } +} + +uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { + uint32_t wi; + uint32_t ei; + uint8_t ring; + int res = xtensa_tlb_lookup(env, v, dtlb, &wi, &ei, &ring); + + switch (res) { + case 0: + if (ring >= xtensa_get_ring(env)) { + return (v & 0xfffff000) | wi | (dtlb ? 0x10 : 0x8); + } + break; + + case INST_TLB_MULTI_HIT_CAUSE: + case LOAD_STORE_TLB_MULTI_HIT_CAUSE: + HELPER(exception_cause_vaddr)(env, env->pc, res, v); + break; + } + return 0; + } else { + return (v & REGION_PAGE_MASK) | 0x1; + } +} + +void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb) +{ + uint32_t vpn; + uint32_t wi; + uint32_t ei; + split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei); + xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, p); +} + /*! * Convert MMU ATTR to PAGE_{READ,WRITE,EXEC} mask. * See ISA, 4.6.5.10 From patchwork Tue May 14 20:44:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943737 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EF92E933 for ; Tue, 14 May 2019 20:59:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DBD6428754 for ; Tue, 14 May 2019 20:59:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CABCA28868; Tue, 14 May 2019 20:59:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6136728754 for ; Tue, 14 May 2019 20:59:43 +0000 (UTC) Received: from localhost ([127.0.0.1]:54041 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeWU-0000cM-4V for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 16:59:42 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeUz-0007pr-OZ for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIW-0007Fc-36 for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:17 -0400 Received: from mail-lf1-x144.google.com ([2a00:1450:4864:20::144]:35271) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIV-0007Bz-Fg for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:16 -0400 Received: by mail-lf1-x144.google.com with SMTP id c17so261317lfi.2 for ; Tue, 14 May 2019 13:45:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6XuVQs+UbdqBAxCFcAT1em7q9SaDATzG83gL/sJvK+Y=; b=HVQFqmA4xlQXaLzwLSp4bPZD8cQeF+msCahRfoJdaD/Qi+IvYwqtEqOOiYD5ZQgESE QGKdzrLN/uISL9pvNrE96nbdlbrJk8BjccYjtsQDzKLyMOdMStVhPUzzSjORQXNaP6sk xwqXi9+bzgt6p3M++O0+75YUjzPXqZGOTV2PCzqayDaw6uhDbRXfLaKf+xpXwWqpLEjV PvbWHJmP9Kh93mF8B1SGnteJbVEhnGoEPWTCdsZvnS5rja+JtnkLRrzygeecsTDvlOlQ OUfqHnYCisK5x63ak6Sz+6bTIiL+gehccJBhzlk2j3IZT9TjSdajnfDQTyear29Oncx3 p5/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6XuVQs+UbdqBAxCFcAT1em7q9SaDATzG83gL/sJvK+Y=; b=cxe3WCf0S0sxEDBYkoagcR1gZP6w0wzEkJnWPfFoeAZykC9PAQSqpx8GoHOjSqpOeo f4hHxAWJLHsVeC5lcGZeVBQFXQpkwEx8ZIHLW9ytZTEJik0l+qMAFZ3plRV95lLnhNq2 1Rl7M1S92iCzT6C9O9RIEwegkIk+2Gm9PYJgyyIHWNezI98OVRP4wqcqCP1i9Kqk7/55 kG3mP9i0yUFi3w014AWTT8Tjk8ku1GhKFRvG+oFtD8y6d+0ku3uVO3oBkzv2Pih+427m zXThDfQm4lTNyXINOD644b4foSEbf0HhKA1viTmibOH1bw5+01CV7qyBD8OZGl+ScyvG uRFg== X-Gm-Message-State: APjAAAVeBT5XQ1CeHfzk1I8SBDuV6gZp5X9FTspsSpk/HUkbLe1W53sE XuFbAHRuhUSTiMBOw4+rMFhtExO/6RQ= X-Google-Smtp-Source: APXvYqwgaB+XP3GWIHAopJCdjUY/U1ovWNM0GiU3jbX/UUmfdjvKPPQxcjv+D4xWGzqWMlPoKMssgA== X-Received: by 2002:ac2:41da:: with SMTP id d26mr17719241lfi.34.1557866714106; Tue, 14 May 2019 13:45:14 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:13 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:41 -0700 Message-Id: <20190514204447.17486-4-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::144 Subject: [Qemu-devel] [PATCH 3/9] target/xtensa: define IDMA and gather/scatter IRQ types X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP IDMA and scatter/gather features introduced new IRQ types that overlay_tool.h need to initialize Xtensa configuration. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 3 +++ target/xtensa/overlay_tool.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 502d41688365..d4258fcc6199 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -298,6 +298,9 @@ typedef enum { INTTYPE_DEBUG, INTTYPE_WRITE_ERR, INTTYPE_PROFILING, + INTTYPE_IDMA_DONE, + INTTYPE_IDMA_ERR, + INTTYPE_GS_ERR, INTTYPE_MAX } interrupt_type; diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index ea07576bc921..8b380ce5e329 100644 --- a/target/xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h @@ -200,6 +200,9 @@ #define XTHAL_INTTYPE_TBD2 INTTYPE_WRITE_ERR #define XTHAL_INTTYPE_WRITE_ERROR INTTYPE_WRITE_ERR #define XTHAL_INTTYPE_PROFILING INTTYPE_PROFILING +#define XTHAL_INTTYPE_IDMA_DONE INTTYPE_IDMA_DONE +#define XTHAL_INTTYPE_IDMA_ERR INTTYPE_IDMA_ERR +#define XTHAL_INTTYPE_GS_ERR INTTYPE_GS_ERR #define INTERRUPT(i) { \ From patchwork Tue May 14 20:44:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943751 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6F5CC92A for ; Tue, 14 May 2019 21:08:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 543CF287CE for ; Tue, 14 May 2019 21:08:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 476CB28868; Tue, 14 May 2019 21:08:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AC434287CE for ; Tue, 14 May 2019 21:08:39 +0000 (UTC) Received: from localhost ([127.0.0.1]:54222 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQef8-00072g-QK for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:08:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV4-0007lu-PB for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIi-0007W1-I0 for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:30 -0400 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:36819) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIb-0007H4-Pi for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:23 -0400 Received: by mail-lj1-x242.google.com with SMTP id z1so510734ljb.3 for ; Tue, 14 May 2019 13:45:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hm1pySXCYRyqzKQMsacqw1+6viA6OKMUTJF5TynmyL0=; b=S0V2dexG17iC1iWmg+LukVUPWeX1ZOy5gO3+sUlQ5TK+8MjfHAKuNQLAG5PCIlMBgs jt57yZO9B2RFndZp/f+URFr6hNF/CpO4IrLtKhiqV7EZlruqXoIHMd5PLHeupxO17NgN 0Kw40ImRwSgmCdgNV6YXvhYZnPRNChGeYtIZy99r8ajeSjECTY/RAr497duWK6Ii3Lcm pUVO3BWJX4Cww8rfzaVaZ9bx8Sck/cH0vEU4ucEOcVBUIdUuoohul05328F4e2p2NfSt bOgK3Lw4nBfc9k+PX15M7hgScwKmnGq+bmOibsk2B1C0N7kzMs4C7upNPihwN9wVlT5g c7fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hm1pySXCYRyqzKQMsacqw1+6viA6OKMUTJF5TynmyL0=; b=eou27rs+Bm6wodf5ffh5D2sj2T6Xbc2UbPhSvhEokP5GAzcAOt63eygjKPgOymgL9B npFvql53cHpRGQJrRpWXPObRZWYg422i0Tnjgd/nonfUXnwnTJUMyCbvWszMi/mVZdQY 9t9+B+IwMZ/XC+L+cfRrd/bFvWADW0+TD42wE4UJOf+xUrWqCjud7uj1KJvy9xGS9my7 So7vw1xKn+UIGdtudIfoNye8pWltlhPjtb1cJAQxcOambilFjXLVEm0t7ZOX2Wx2ZXOL rjPYPPjf8ngLE1paPHaBYKd/gvd6vR0/ipQZkCEYzHREblYw+hdycDInWKPXIBlApRna wBkg== X-Gm-Message-State: APjAAAVeaczYq+QlBh/p5o1HWWwdhiS7P/bzBz2UZrhhBZR+mEeLbiR7 ZF5pvjid9IFYBBOoFPxMIj5X+12RgOQ= X-Google-Smtp-Source: APXvYqyR923CIrLtuXBWFXuI2Fa22yH/Ancp6Sr+NSy0RmG6NtMMSuJTCHfWndqKX1e/GVLOasKmew== X-Received: by 2002:a2e:9a1a:: with SMTP id o26mr3344579lji.174.1557866716300; Tue, 14 May 2019 13:45:16 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:15 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:42 -0700 Message-Id: <20190514204447.17486-5-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::242 Subject: [Qemu-devel] [PATCH 4/9] target/xtensa: add parity/ECC option SRs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add SRs and rsr/wsr/xsr opcodes defined by the parity/ECC xtensa option. The implementation is trivial since we don't emulate parity/ECC yet. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 6 ++ target/xtensa/overlay_tool.h | 2 + target/xtensa/translate.c | 162 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index d4258fcc6199..74ee7d125360 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -144,6 +144,12 @@ enum { CACHEATTR = 98, ATOMCTL = 99, DDR = 104, + MEPC = 106, + MEPS = 107, + MESAVE = 108, + MESR = 109, + MECR = 110, + MEVADDR = 111, IBREAKA = 128, DBREAKA = 144, DBREAKC = 160, diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index 8b380ce5e329..ffaab4b094cc 100644 --- a/target/xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h @@ -112,6 +112,8 @@ XCHAL_OPTION(XCHAL_DCACHE_LINE_LOCKABLE, \ XTENSA_OPTION_DCACHE_INDEX_LOCK) | \ XCHAL_OPTION(XCHAL_UNALIGNED_LOAD_HW, XTENSA_OPTION_HW_ALIGNMENT) | \ + XCHAL_OPTION(XCHAL_HAVE_MEM_ECC_PARITY, \ + XTENSA_OPTION_MEMORY_ECC_PARITY) | \ /* Memory protection and translation */ \ XCHAL_OPTION(XCHAL_HAVE_MIMIC_CACHEATTR, \ XTENSA_OPTION_REGION_PROTECTION) | \ diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 100d6e126590..63a90fdd17dc 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -4216,6 +4216,60 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "rsr.mecr", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MECR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.mepc", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPC, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.meps", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPS, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.mesave", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESAVE, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.mesr", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.mevaddr", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "rsr.misc0", .translate = translate_rsr, .test_ill = test_ill_sr, @@ -5036,6 +5090,60 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "wsr.mecr", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MECR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "wsr.mepc", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPC, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "wsr.meps", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPS, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "wsr.mesave", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESAVE, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "wsr.mesr", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "wsr.mevaddr", + .translate = translate_wsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "wsr.misc0", .translate = translate_wsr, .test_ill = test_ill_sr, @@ -5702,6 +5810,60 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){MEMCTL}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "xsr.mecr", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MECR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "xsr.mepc", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPC, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "xsr.meps", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MEPS, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "xsr.mesave", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESAVE, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "xsr.mesr", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "xsr.mevaddr", + .translate = translate_xsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MESR, + XTENSA_OPTION_MEMORY_ECC_PARITY, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "xsr.misc0", .translate = translate_xsr, .test_ill = test_ill_sr, From patchwork Tue May 14 20:44:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943749 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2A29C924 for ; Tue, 14 May 2019 21:06:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1409F287CE for ; Tue, 14 May 2019 21:06:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0476628868; Tue, 14 May 2019 21:06:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7DA81287CE for ; Tue, 14 May 2019 21:06:38 +0000 (UTC) Received: from localhost ([127.0.0.1]:54200 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQedB-0005Yb-Oj for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:06:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:38829) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV3-0007X1-Eo for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIj-0007XS-4W for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:32 -0400 Received: from mail-lj1-x244.google.com ([2a00:1450:4864:20::244]:44965) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeId-0007PN-E4 for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:28 -0400 Received: by mail-lj1-x244.google.com with SMTP id e13so466778ljl.11 for ; Tue, 14 May 2019 13:45:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BcH00gQ3TIulNwsNHVK3TUj8Vja71dKWcTQcNQsozMQ=; b=vJ+s9feedeMjD6ToBPPgZrVZj+gyVOCYJbOoCPekPbarZo0FfVoLRpP6+hAUOb5Laq 2F9HIHVSKzwZHvx8lvM3FpUZwRU9MdNrjQG9e5neL5DkL5cWuSIQysiWYO1KFfsG3gGY HYmNhkEnNunYOnCwPKVhFGbN4QXy+dwI668Go3R84Evs7/baBSWCnuE4QnSoprcQP5ko DhenypZjwygXIes0hfcLivSo6tXGPMs+JCfztWevQonik6rctEdhTy+kTpPiL3WVrIC+ ZYim7BJMaHoD50u+YovNfV5PN6Y7lqw2E7NZtv5FZGPzFjHCLPOuJ2HyC9AssGS+bLoZ CfiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BcH00gQ3TIulNwsNHVK3TUj8Vja71dKWcTQcNQsozMQ=; b=DYDa/xBtNNOm9iR62bsN4fCm4Xujwjd4a5d5EsrHXEGUxXJUWvETNsqjugh1ikokQo HfGN4TIsH70M4u+VxyzM3sJx5ePNOszkrV4fyo9vZftij0JRzGT3YAYeA+QQUIgKb97p D4pr1qQcZHB77qBnKrfgL22ixF2NP/hYrqvlIv8SaO6L8ClrQqxJ4HARSCXYqZgNTDTE FR6qrEsPBb8e6fOqAHkB2hWbLi6HosccK/WjbobfSIla24nI46C9DtDzOO1vYD1WBrTB DikNNHXk84bR77ZUbuX7hPY+v9NSkEsQsQ1SE5xVKbEY+LcnYsZwyorzAvgTuWesscfk owow== X-Gm-Message-State: APjAAAWFNALSbA44Qoj0TJ3oxhw9lJa3zktt60wooAyM59QtuuEEeT32 kK84ONvcIg2aUkgMWjbvtwpwlLSXzxg= X-Google-Smtp-Source: APXvYqy7UPLFdJL48ITHSZ4EDDbJm8jbGDgEX3mYDzImbppxCzN7PQVEzsWJakvkrWHAClczPVpDNA== X-Received: by 2002:a2e:4b19:: with SMTP id y25mr17313887lja.149.1557866718655; Tue, 14 May 2019 13:45:18 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:18 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:43 -0700 Message-Id: <20190514204447.17486-6-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::244 Subject: [Qemu-devel] [PATCH 5/9] target/xtensa: implement MPU option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The Memory Protection Unit Option (MPU) is a combined instruction and data memory protection unit with more protection flexibility than the Region Protection Option or the Region Translation Option but without any translation capability. It does no demand paging and does not reference a memory-based page table. Add memory protection unit option, internal state, SRs and opcodes. Implement MPU entries dumping in dump_mmu. Signed-off-by: Max Filippov --- target/xtensa/cpu.c | 1 - target/xtensa/cpu.h | 17 ++ target/xtensa/helper.h | 5 + target/xtensa/mmu_helper.c | 369 +++++++++++++++++++++++++++++++++++++++++++ target/xtensa/overlay_tool.h | 29 ++++ target/xtensa/translate.c | 146 +++++++++++++++++ 6 files changed, 566 insertions(+), 1 deletion(-) diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index a54dbe42602d..4215a1881ec7 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -78,7 +78,6 @@ static void xtensa_cpu_reset(CPUState *s) env->sregs[VECBASE] = env->config->vecbase; env->sregs[IBREAKENABLE] = 0; env->sregs[MEMCTL] = MEMCTL_IL0EN & env->config->memctl_mask; - env->sregs[CACHEATTR] = 0x22222222; env->sregs[ATOMCTL] = xtensa_option_enabled(env->config, XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15; env->sregs[CONFIGID0] = env->config->configid[0]; diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 74ee7d125360..d6e6bf6ca183 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -99,6 +99,7 @@ enum { /* Memory protection and translation */ XTENSA_OPTION_REGION_PROTECTION, XTENSA_OPTION_REGION_TRANSLATION, + XTENSA_OPTION_MPU, XTENSA_OPTION_MMU, XTENSA_OPTION_CACHEATTR, @@ -137,11 +138,15 @@ enum { PTEVADDR = 83, MMID = 89, RASID = 90, + MPUENB = 90, ITLBCFG = 91, DTLBCFG = 92, + MPUCFG = 92, + ERACCESS = 95, IBREAKENABLE = 96, MEMCTL = 97, CACHEATTR = 98, + CACHEADRDIS = 98, ATOMCTL = 99, DDR = 104, MEPC = 106, @@ -234,6 +239,7 @@ enum { #define MAX_TLB_WAY_SIZE 8 #define MAX_NDBREAK 2 #define MAX_NMEMORY 4 +#define MAX_MPU_FOREGROUND_SEGMENTS 32 #define REGION_PAGE_MASK 0xe0000000 @@ -327,6 +333,11 @@ typedef struct xtensa_tlb { unsigned nrefillentries; } xtensa_tlb; +typedef struct xtensa_mpu_entry { + uint32_t vaddr; + uint32_t attr; +} xtensa_mpu_entry; + typedef struct XtensaGdbReg { int targno; unsigned flags; @@ -477,6 +488,11 @@ struct XtensaConfig { xtensa_tlb itlb; xtensa_tlb dtlb; + + uint32_t mpu_align; + unsigned n_mpu_fg_segments; + unsigned n_mpu_bg_segments; + const xtensa_mpu_entry *mpu_bg; }; typedef struct XtensaConfigList { @@ -513,6 +529,7 @@ typedef struct CPUXtensaState { #ifndef CONFIG_USER_ONLY xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE]; + xtensa_mpu_entry mpu_fg[MAX_MPU_FOREGROUND_SEGMENTS]; unsigned autorefill_idx; bool runstall; AddressSpace *address_space_er; diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index 0b9ec670c86e..9216bee57e9a 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -33,6 +33,11 @@ DEF_HELPER_FLAGS_3(rtlb1, TCG_CALL_NO_RWG_SE, i32, env, i32, i32) DEF_HELPER_3(itlb, void, env, i32, i32) DEF_HELPER_3(ptlb, i32, env, i32, i32) DEF_HELPER_4(wtlb, void, env, i32, i32, i32) +DEF_HELPER_2(wsr_mpuenb, void, env, i32) +DEF_HELPER_3(wptlb, void, env, i32, i32) +DEF_HELPER_FLAGS_2(rptlb0, TCG_CALL_NO_RWG_SE, i32, env, i32) +DEF_HELPER_FLAGS_2(rptlb1, TCG_CALL_NO_RWG_SE, i32, env, i32) +DEF_HELPER_2(pptlb, i32, env, i32) DEF_HELPER_2(wsr_ibreakenable, void, env, i32) DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32) diff --git a/target/xtensa/mmu_helper.c b/target/xtensa/mmu_helper.c index 465cfbf61359..cab39f687a21 100644 --- a/target/xtensa/mmu_helper.c +++ b/target/xtensa/mmu_helper.c @@ -35,6 +35,31 @@ #include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#define XTENSA_MPU_SEGMENT_MASK 0x0000001f +#define XTENSA_MPU_ACC_RIGHTS_MASK 0x00000f00 +#define XTENSA_MPU_ACC_RIGHTS_SHIFT 8 +#define XTENSA_MPU_MEM_TYPE_MASK 0x001ff000 +#define XTENSA_MPU_MEM_TYPE_SHIFT 12 +#define XTENSA_MPU_ATTR_MASK 0x001fff00 + +#define XTENSA_MPU_PROBE_B 0x40000000 +#define XTENSA_MPU_PROBE_V 0x80000000 + +#define XTENSA_MPU_SYSTEM_TYPE_DEVICE 0x0001 +#define XTENSA_MPU_SYSTEM_TYPE_NC 0x0002 +#define XTENSA_MPU_SYSTEM_TYPE_C 0x0003 +#define XTENSA_MPU_SYSTEM_TYPE_MASK 0x0003 + +#define XTENSA_MPU_TYPE_SYS_C 0x0010 +#define XTENSA_MPU_TYPE_SYS_W 0x0020 +#define XTENSA_MPU_TYPE_SYS_R 0x0040 +#define XTENSA_MPU_TYPE_CPU_C 0x0100 +#define XTENSA_MPU_TYPE_CPU_W 0x0200 +#define XTENSA_MPU_TYPE_CPU_R 0x0400 +#define XTENSA_MPU_TYPE_CPU_CACHE 0x0800 +#define XTENSA_MPU_TYPE_B 0x1000 +#define XTENSA_MPU_TYPE_INT 0x2000 + void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr) { /* @@ -382,7 +407,20 @@ void reset_mmu(CPUXtensaState *env) reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb); reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb); reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb); + } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { + unsigned i; + + env->sregs[MPUENB] = 0; + env->sregs[MPUCFG] = env->config->n_mpu_fg_segments; + env->sregs[CACHEADRDIS] = 0; + assert(env->config->n_mpu_bg_segments > 0 && + env->config->mpu_bg[0].vaddr == 0); + for (i = 1; i < env->config->n_mpu_bg_segments; ++i) { + assert(env->config->mpu_bg[i].vaddr >= + env->config->mpu_bg[i - 1].vaddr); + } } else { + env->sregs[CACHEATTR] = 0x22222222; reset_tlb_region_way0(env, env->itlb); reset_tlb_region_way0(env, env->dtlb); } @@ -579,6 +617,149 @@ static unsigned cacheattr_attr_to_access(uint32_t attr) return access[attr & 0xf]; } +struct attr_pattern { + uint32_t mask; + uint32_t value; +}; + +static int attr_pattern_match(uint32_t attr, + const struct attr_pattern *pattern, + size_t n) +{ + size_t i; + + for (i = 0; i < n; ++i) { + if ((attr & pattern[i].mask) == pattern[i].value) { + return 1; + } + } + return 0; +} + +static unsigned mpu_attr_to_cpu_cache(uint32_t attr) +{ + static const struct attr_pattern cpu_c[] = { + { .mask = 0x18f, .value = 0x089 }, + { .mask = 0x188, .value = 0x080 }, + { .mask = 0x180, .value = 0x180 }, + }; + + unsigned type = 0; + + if (attr_pattern_match(attr, cpu_c, ARRAY_SIZE(cpu_c))) { + type |= XTENSA_MPU_TYPE_CPU_CACHE; + if (attr & 0x10) { + type |= XTENSA_MPU_TYPE_CPU_C; + } + if (attr & 0x20) { + type |= XTENSA_MPU_TYPE_CPU_W; + } + if (attr & 0x40) { + type |= XTENSA_MPU_TYPE_CPU_R; + } + } + return type; +} + +static unsigned mpu_attr_to_type(uint32_t attr) +{ + static const struct attr_pattern device_type[] = { + { .mask = 0x1f6, .value = 0x000 }, + { .mask = 0x1f6, .value = 0x006 }, + }; + static const struct attr_pattern sys_nc_type[] = { + { .mask = 0x1fe, .value = 0x018 }, + { .mask = 0x1fe, .value = 0x01e }, + { .mask = 0x18f, .value = 0x089 }, + }; + static const struct attr_pattern sys_c_type[] = { + { .mask = 0x1f8, .value = 0x010 }, + { .mask = 0x188, .value = 0x080 }, + { .mask = 0x1f0, .value = 0x030 }, + { .mask = 0x180, .value = 0x180 }, + }; + static const struct attr_pattern b[] = { + { .mask = 0x1f7, .value = 0x001 }, + { .mask = 0x1f7, .value = 0x007 }, + { .mask = 0x1ff, .value = 0x019 }, + { .mask = 0x1ff, .value = 0x01f }, + }; + + unsigned type = 0; + + attr = (attr & XTENSA_MPU_MEM_TYPE_MASK) >> XTENSA_MPU_MEM_TYPE_SHIFT; + if (attr_pattern_match(attr, device_type, ARRAY_SIZE(device_type))) { + type |= XTENSA_MPU_SYSTEM_TYPE_DEVICE; + if (attr & 0x80) { + type |= XTENSA_MPU_TYPE_INT; + } + } + if (attr_pattern_match(attr, sys_nc_type, ARRAY_SIZE(sys_nc_type))) { + type |= XTENSA_MPU_SYSTEM_TYPE_NC; + } + if (attr_pattern_match(attr, sys_c_type, ARRAY_SIZE(sys_c_type))) { + type |= XTENSA_MPU_SYSTEM_TYPE_C; + if (attr & 0x1) { + type |= XTENSA_MPU_TYPE_SYS_C; + } + if (attr & 0x2) { + type |= XTENSA_MPU_TYPE_SYS_W; + } + if (attr & 0x4) { + type |= XTENSA_MPU_TYPE_SYS_R; + } + } + if (attr_pattern_match(attr, b, ARRAY_SIZE(b))) { + type |= XTENSA_MPU_TYPE_B; + } + type |= mpu_attr_to_cpu_cache(attr); + + return type; +} + +static unsigned mpu_attr_to_access(uint32_t attr, unsigned ring) +{ + static const unsigned access[2][16] = { + [0] = { + [4] = PAGE_READ, + [5] = PAGE_READ | PAGE_EXEC, + [6] = PAGE_READ | PAGE_WRITE, + [7] = PAGE_READ | PAGE_WRITE | PAGE_EXEC, + [8] = PAGE_WRITE, + [9] = PAGE_READ | PAGE_WRITE, + [10] = PAGE_READ | PAGE_WRITE, + [11] = PAGE_READ | PAGE_WRITE | PAGE_EXEC, + [12] = PAGE_READ, + [13] = PAGE_READ | PAGE_EXEC, + [14] = PAGE_READ | PAGE_WRITE, + [15] = PAGE_READ | PAGE_WRITE | PAGE_EXEC, + }, + [1] = { + [8] = PAGE_WRITE, + [9] = PAGE_READ | PAGE_WRITE | PAGE_EXEC, + [10] = PAGE_READ, + [11] = PAGE_READ | PAGE_EXEC, + [12] = PAGE_READ, + [13] = PAGE_READ | PAGE_EXEC, + [14] = PAGE_READ | PAGE_WRITE, + [15] = PAGE_READ | PAGE_WRITE | PAGE_EXEC, + }, + }; + unsigned rv; + unsigned type; + + type = mpu_attr_to_cpu_cache(attr); + rv = access[ring != 0][(attr & XTENSA_MPU_ACC_RIGHTS_MASK) >> + XTENSA_MPU_ACC_RIGHTS_SHIFT]; + + if (type & XTENSA_MPU_TYPE_CPU_CACHE) { + rv |= (type & XTENSA_MPU_TYPE_CPU_C) ? PAGE_CACHE_WB : PAGE_CACHE_WT; + } else { + rv |= PAGE_CACHE_BYPASS; + } + return rv; +} + static bool is_access_granted(unsigned access, int is_write) { switch (is_write) { @@ -723,6 +904,129 @@ static int get_physical_addr_region(CPUXtensaState *env, return 0; } +static int xtensa_mpu_lookup(const xtensa_mpu_entry *entry, unsigned n, + uint32_t vaddr, unsigned *segment) +{ + unsigned nhits = 0; + unsigned i; + + for (i = 0; i < n; ++i) { + if (vaddr >= entry[i].vaddr && + (i == n - 1 || vaddr < entry[i + 1].vaddr)) { + if (nhits++) { + break; + } + *segment = i; + } + } + return nhits; +} + +void HELPER(wsr_mpuenb)(CPUXtensaState *env, uint32_t v) +{ + XtensaCPU *cpu = xtensa_env_get_cpu(env); + + v &= (2u << (env->config->n_mpu_fg_segments - 1)) - 1; + + if (v != env->sregs[MPUENB]) { + env->sregs[MPUENB] = v; + tlb_flush(CPU(cpu)); + } +} + +void HELPER(wptlb)(CPUXtensaState *env, uint32_t p, uint32_t v) +{ + unsigned segment = p & XTENSA_MPU_SEGMENT_MASK; + + if (segment < env->config->n_mpu_fg_segments) { + env->mpu_fg[segment].vaddr = v & -env->config->mpu_align; + env->mpu_fg[segment].attr = p & XTENSA_MPU_ATTR_MASK; + env->sregs[MPUENB] = deposit32(env->sregs[MPUENB], segment, 1, v); + tlb_flush(CPU(xtensa_env_get_cpu(env))); + } +} + +uint32_t HELPER(rptlb0)(CPUXtensaState *env, uint32_t s) +{ + unsigned segment = s & XTENSA_MPU_SEGMENT_MASK; + + if (segment < env->config->n_mpu_fg_segments) { + return env->mpu_fg[segment].vaddr | + extract32(env->sregs[MPUENB], segment, 1); + } else { + return 0; + } +} + +uint32_t HELPER(rptlb1)(CPUXtensaState *env, uint32_t s) +{ + unsigned segment = s & XTENSA_MPU_SEGMENT_MASK; + + if (segment < env->config->n_mpu_fg_segments) { + return env->mpu_fg[segment].attr; + } else { + return 0; + } +} + +uint32_t HELPER(pptlb)(CPUXtensaState *env, uint32_t v) +{ + unsigned nhits; + unsigned segment = XTENSA_MPU_PROBE_B; + unsigned bg_segment; + + nhits = xtensa_mpu_lookup(env->mpu_fg, env->config->n_mpu_fg_segments, + v, &segment); + if (nhits > 1) { + HELPER(exception_cause_vaddr)(env, env->pc, + LOAD_STORE_TLB_MULTI_HIT_CAUSE, v); + } else if (nhits == 1 && (env->sregs[MPUENB] & (1u << segment))) { + return env->mpu_fg[segment].attr | segment | XTENSA_MPU_PROBE_V; + } else { + xtensa_mpu_lookup(env->config->mpu_bg, + env->config->n_mpu_bg_segments, + v, &bg_segment); + return env->config->mpu_bg[bg_segment].attr | segment; + } +} + +static int get_physical_addr_mpu(CPUXtensaState *env, + uint32_t vaddr, int is_write, int mmu_idx, + uint32_t *paddr, uint32_t *page_size, + unsigned *access) +{ + unsigned nhits; + unsigned segment; + uint32_t attr; + + nhits = xtensa_mpu_lookup(env->mpu_fg, env->config->n_mpu_fg_segments, + vaddr, &segment); + if (nhits > 1) { + return is_write < 2 ? + LOAD_STORE_TLB_MULTI_HIT_CAUSE : + INST_TLB_MULTI_HIT_CAUSE; + } else if (nhits == 1 && (env->sregs[MPUENB] & (1u << segment))) { + attr = env->mpu_fg[segment].attr; + } else { + xtensa_mpu_lookup(env->config->mpu_bg, + env->config->n_mpu_bg_segments, + vaddr, &segment); + attr = env->config->mpu_bg[segment].attr; + } + + *access = mpu_attr_to_access(attr, mmu_idx); + if (!is_access_granted(*access, is_write)) { + return is_write < 2 ? + (is_write ? + STORE_PROHIBITED_CAUSE : + LOAD_PROHIBITED_CAUSE) : + INST_FETCH_PROHIBITED_CAUSE; + } + *paddr = vaddr; + *page_size = env->config->mpu_align; + return 0; +} + /*! * Convert virtual address to physical addr. * MMU may issue pagewalk and change xtensa autorefill TLB way entry. @@ -743,6 +1047,9 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) { return get_physical_addr_region(env, vaddr, is_write, mmu_idx, paddr, page_size, access); + } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { + return get_physical_addr_mpu(env, vaddr, is_write, mmu_idx, + paddr, page_size, access); } else { *paddr = vaddr; *page_size = TARGET_PAGE_SIZE; @@ -810,6 +1117,63 @@ static void dump_tlb(CPUXtensaState *env, bool dtlb) } } +static void dump_mpu(CPUXtensaState *env, + const xtensa_mpu_entry *entry, unsigned n) +{ + unsigned i; + + qemu_printf("\t%s Vaddr Attr Ring0 Ring1 System Type CPU cache\n" + "\t%s ---------- ---------- ----- ----- ------------- ---------\n", + env ? "En" : " ", + env ? "--" : " "); + + for (i = 0; i < n; ++i) { + uint32_t attr = entry[i].attr; + unsigned access0 = mpu_attr_to_access(attr, 0); + unsigned access1 = mpu_attr_to_access(attr, 1); + unsigned type = mpu_attr_to_type(attr); + char cpu_cache = (type & XTENSA_MPU_TYPE_CPU_CACHE) ? '-' : ' '; + + qemu_printf("\t %c 0x%08x 0x%08x %c%c%c %c%c%c ", + env ? + ((env->sregs[MPUENB] & (1u << i)) ? '+' : '-') : ' ', + entry[i].vaddr, attr, + (access0 & PAGE_READ) ? 'R' : '-', + (access0 & PAGE_WRITE) ? 'W' : '-', + (access0 & PAGE_EXEC) ? 'X' : '-', + (access1 & PAGE_READ) ? 'R' : '-', + (access1 & PAGE_WRITE) ? 'W' : '-', + (access1 & PAGE_EXEC) ? 'X' : '-'); + + switch (type & XTENSA_MPU_SYSTEM_TYPE_MASK) { + case XTENSA_MPU_SYSTEM_TYPE_DEVICE: + qemu_printf("Device %cB %3s\n", + (type & XTENSA_MPU_TYPE_B) ? ' ' : 'n', + (type & XTENSA_MPU_TYPE_INT) ? "int" : ""); + break; + case XTENSA_MPU_SYSTEM_TYPE_NC: + qemu_printf("Sys NC %cB %c%c%c\n", + (type & XTENSA_MPU_TYPE_B) ? ' ' : 'n', + (type & XTENSA_MPU_TYPE_CPU_R) ? 'r' : cpu_cache, + (type & XTENSA_MPU_TYPE_CPU_W) ? 'w' : cpu_cache, + (type & XTENSA_MPU_TYPE_CPU_C) ? 'c' : cpu_cache); + break; + case XTENSA_MPU_SYSTEM_TYPE_C: + qemu_printf("Sys C %c%c%c %c%c%c\n", + (type & XTENSA_MPU_TYPE_SYS_R) ? 'R' : '-', + (type & XTENSA_MPU_TYPE_SYS_W) ? 'W' : '-', + (type & XTENSA_MPU_TYPE_SYS_C) ? 'C' : '-', + (type & XTENSA_MPU_TYPE_CPU_R) ? 'r' : cpu_cache, + (type & XTENSA_MPU_TYPE_CPU_W) ? 'w' : cpu_cache, + (type & XTENSA_MPU_TYPE_CPU_C) ? 'c' : cpu_cache); + break; + default: + qemu_printf("Unknown\n"); + break; + } + } +} + void dump_mmu(CPUXtensaState *env) { if (xtensa_option_bits_enabled(env->config, @@ -821,6 +1185,11 @@ void dump_mmu(CPUXtensaState *env) dump_tlb(env, false); qemu_printf("\nDTLB:\n"); dump_tlb(env, true); + } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { + qemu_printf("Foreground map:\n"); + dump_mpu(env, env->mpu_fg, env->config->n_mpu_fg_segments); + qemu_printf("\nBackground map:\n"); + dump_mpu(NULL, env->config->mpu_bg, env->config->n_mpu_bg_segments); } else { qemu_printf("No TLB for this CPU core\n"); } diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index ffaab4b094cc..b61c92539861 100644 --- a/target/xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h @@ -72,6 +72,10 @@ #define XCHAL_HAVE_EXTERN_REGS 0 #endif +#ifndef XCHAL_HAVE_MPU +#define XCHAL_HAVE_MPU 0 +#endif + #define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0) #define XTENSA_OPTIONS ( \ @@ -119,6 +123,7 @@ XTENSA_OPTION_REGION_PROTECTION) | \ XCHAL_OPTION(XCHAL_HAVE_XLT_CACHEATTR, \ XTENSA_OPTION_REGION_TRANSLATION) | \ + XCHAL_OPTION(XCHAL_HAVE_MPU, XTENSA_OPTION_MPU) | \ XCHAL_OPTION(XCHAL_HAVE_PTP_MMU, XTENSA_OPTION_MMU) | \ XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \ /* Other, TODO */ \ @@ -361,6 +366,30 @@ #define XCHAL_SYSRAM0_SIZE 0x04000000 #endif +#elif XCHAL_HAVE_MPU + +#ifndef XTENSA_MPU_BG_MAP +#define XTENSA_MPU_BG_MAP (xtensa_mpu_entry []){\ + { .vaddr = 0, .attr = 0x00006700, }, \ +} +#endif + +#define TLB_SECTION \ + .mpu_align = XCHAL_MPU_ALIGN, \ + .n_mpu_fg_segments = XCHAL_MPU_ENTRIES, \ + .n_mpu_bg_segments = 1, \ + .mpu_bg = XTENSA_MPU_BG_MAP + +#ifndef XCHAL_SYSROM0_PADDR +#define XCHAL_SYSROM0_PADDR 0x50000000 +#define XCHAL_SYSROM0_SIZE 0x04000000 +#endif + +#ifndef XCHAL_SYSRAM0_PADDR +#define XCHAL_SYSRAM0_PADDR 0x60000000 +#define XCHAL_SYSRAM0_SIZE 0x04000000 +#endif + #else #ifndef XCHAL_SYSROM0_PADDR diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 63a90fdd17dc..782f2ec62099 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -1992,6 +1992,15 @@ static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[], #endif } +static void translate_pptlb(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + tcg_gen_movi_i32(cpu_pc, dc->pc); + gen_helper_pptlb(arg[0].out, cpu_env, arg[1].in); +#endif +} + static void translate_quos(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -2184,6 +2193,22 @@ static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], #endif } +static void translate_rptlb0(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_rptlb0(arg[0].out, cpu_env, arg[1].in); +#endif +} + +static void translate_rptlb1(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_rptlb1(arg[0].out, cpu_env, arg[1].in); +#endif +} + static void translate_rur(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -2445,6 +2470,14 @@ static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[], #endif } +static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_wptlb(cpu_env, arg[0].in, arg[1].in); +#endif +} + static void translate_wer(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -2593,6 +2626,14 @@ static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[], #endif } +static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ +#ifndef CONFIG_USER_ONLY + gen_helper_wsr_mpuenb(cpu_env, arg[0].in); +#endif +} + static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -2731,6 +2772,7 @@ gen_translate_xsr(ibreaka) gen_translate_xsr(ibreakenable) gen_translate_xsr(icount) gen_translate_xsr(memctl) +gen_translate_xsr(mpuenb) gen_translate_xsr(ps) gen_translate_xsr(rasid) gen_translate_xsr(sar) @@ -3581,6 +3623,10 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){false}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "pptlb", + .translate = translate_pptlb, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "quos", .translate = translate_quos, .par = (const uint32_t[]){true}, @@ -3667,6 +3713,14 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){false, 1}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "rptlb0", + .translate = translate_rptlb0, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rptlb1", + .translate = translate_rptlb1, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "rotw", .translate = translate_rotw, .op_flags = XTENSA_OP_PRIVILEGED | @@ -3723,6 +3777,15 @@ static const XtensaOpcodeOps core_ops[] = { XTENSA_OPTION_BOOLEAN, }, }, { + .name = "rsr.cacheadrdis", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEADRDIS, + XTENSA_OPTION_MPU, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "rsr.cacheattr", .translate = translate_rsr, .test_ill = test_ill_sr, @@ -3976,6 +4039,11 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "rsr.eraccess", + .translate = translate_rsr, + .par = (const uint32_t[]){ERACCESS}, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "rsr.exccause", .translate = translate_rsr, .test_ill = test_ill_sr, @@ -4306,6 +4374,24 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "rsr.mpucfg", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MPUCFG, + XTENSA_OPTION_MPU, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { + .name = "rsr.mpuenb", + .translate = translate_rsr, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MPUENB, + XTENSA_OPTION_MPU, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "rsr.prefctl", .translate = translate_rsr, .par = (const uint32_t[]){PREFCTL}, @@ -4543,6 +4629,10 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){false}, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, }, { + .name = "wptlb", + .translate = translate_wptlb, + .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + }, { .name = "wrmsk_expstate", .translate = translate_wrmsk_expstate, }, { @@ -4587,6 +4677,16 @@ static const XtensaOpcodeOps core_ops[] = { 0xffff, }, }, { + .name = "wsr.cacheadrdis", + .translate = translate_wsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEADRDIS, + XTENSA_OPTION_MPU, + 0xff, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "wsr.cacheattr", .translate = translate_wsr, .test_ill = test_ill_sr, @@ -4832,6 +4932,15 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "wsr.eraccess", + .translate = translate_wsr_mask, + .par = (const uint32_t[]){ + ERACCESS, + 0, + 0xffff, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "wsr.exccause", .translate = translate_wsr, .test_ill = test_ill_sr, @@ -5189,6 +5298,15 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "wsr.mpuenb", + .translate = translate_wsr_mpuenb, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MPUENB, + XTENSA_OPTION_MPU, + }, + .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + }, { .name = "wsr.prefctl", .translate = translate_wsr, .par = (const uint32_t[]){PREFCTL}, @@ -5334,6 +5452,16 @@ static const XtensaOpcodeOps core_ops[] = { 0xffff, }, }, { + .name = "xsr.cacheadrdis", + .translate = translate_xsr_mask, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + CACHEADRDIS, + XTENSA_OPTION_MPU, + 0xff, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "xsr.cacheattr", .translate = translate_xsr, .test_ill = test_ill_sr, @@ -5579,6 +5707,15 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "xsr.eraccess", + .translate = translate_xsr_mask, + .par = (const uint32_t[]){ + ERACCESS, + 0, + 0xffff, + }, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "xsr.exccause", .translate = translate_xsr, .test_ill = test_ill_sr, @@ -5900,6 +6037,15 @@ static const XtensaOpcodeOps core_ops[] = { }, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "xsr.mpuenb", + .translate = translate_xsr_mpuenb, + .test_ill = test_ill_sr, + .par = (const uint32_t[]){ + MPUENB, + XTENSA_OPTION_MPU, + }, + .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + }, { .name = "xsr.prefctl", .translate = translate_xsr, .par = (const uint32_t[]){PREFCTL}, From patchwork Tue May 14 20:44:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943743 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9092E92A for ; Tue, 14 May 2019 21:03:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E88E287CE for ; Tue, 14 May 2019 21:03:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F3D42887B; Tue, 14 May 2019 21:03:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 19C8C287CE for ; Tue, 14 May 2019 21:03:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:54128 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeaa-0003d8-9P for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:03:56 -0400 Received: from eggs.gnu.org ([209.51.188.92]:38994) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV3-0007lR-Lb for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIj-0007XG-3n for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:30 -0400 Received: from mail-lj1-x244.google.com ([2a00:1450:4864:20::244]:46154) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeId-0007Rh-Km for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:28 -0400 Received: by mail-lj1-x244.google.com with SMTP id h21so458588ljk.13 for ; Tue, 14 May 2019 13:45:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TNwKj3NK4xpLU3quun8/1/87vC9zwSKuxU85t6b9WuA=; b=naeemU+B3Dsr9Pb9887eyk9hKazrAQqLIV+zE8jsRV/UhSUadUFy0KyFnlfRBpaCal cH5oBrYFH9kZHO4qk1Ylhs+GdZzJ3+izuEaT+3SaJ74WucyLnkYyh8xdIuhr6X6Hmlzk JEsGweJwKd+4iCVEQvos2czMF0zpB7Qt2ih5U+Q/yEgeiDO0ybkIhQfhp6oJOh7DcolC wPFvw5VTQaIoHsHEatmfGLT8y64nMk4iAgTm9WAZtIJdo0mpCPcY8mBu/FqGAktC672a kJSYp6Qfv3272bPzlQi9hubtMYdoBFPCo85QGI6PcBbhlZiIckFyvjjCwARCGADdJzjQ VDXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TNwKj3NK4xpLU3quun8/1/87vC9zwSKuxU85t6b9WuA=; b=eZUESdFylfK1LIxPo6sBUzoLB4rQAfeUTlzaBpRDLyMTD5cmseHePEbX1e0dlYSrBJ 6cw8jeEyVllOZIaqduLpH+Byb3qt43jADzfdikXWhDuB9hn2zh6a/2J4fI6BZBrGBVBx yg94oUmBFUg3i73Fp4kDEdIUB4znN47ldAgJc7SCu3bZj+a7k1xxhcKzqRkbznT98HOy IvgZlaMgNffYmb97AYYeWhwj2Xz9WiZlH1CYt2VoyQqSm0x6gtSOCat56TVz8PR5X6c+ COQLZQheCtRqDvuuKL81okSzfM8PcXdkk0tmo2JMEK+Nwd98SCgIQ3RAYgHG0Vx+wkjE iKNQ== X-Gm-Message-State: APjAAAXMWbKAuZyjpcvLw3q5Qt9Yu7g7rNAS6Gw7uk5kxSx7XdiR3wgv riREi7sPYGAHb/LQw59mtoQFlrAkT24= X-Google-Smtp-Source: APXvYqyyEJ5GTQ6YtPzM+dXpqNHh6PtiJL6IchaRThMLl/uTogIYxWtOkLS8WrcnXck1CHXzchdDNg== X-Received: by 2002:a2e:28d:: with SMTP id y13mr17667712lje.177.1557866720808; Tue, 14 May 2019 13:45:20 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:20 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:44 -0700 Message-Id: <20190514204447.17486-7-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::244 Subject: [Qemu-devel] [PATCH 6/9] target/xtensa: implement DIWBUI.P opcode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This is a recent addition to the set of data cache opcodes. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 1 + target/xtensa/overlay_tool.h | 1 + target/xtensa/translate.c | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index d6e6bf6ca183..ba4ef2b6a729 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -466,6 +466,7 @@ struct XtensaConfig { unsigned icache_ways; unsigned dcache_ways; + unsigned dcache_line_bytes; uint32_t memctl_mask; XtensaMemory instrom; diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index b61c92539861..4925b21f0edf 100644 --- a/target/xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h @@ -425,6 +425,7 @@ #define CACHE_SECTION \ .icache_ways = XCHAL_ICACHE_WAYS, \ .dcache_ways = XCHAL_DCACHE_WAYS, \ + .dcache_line_bytes = XCHAL_DCACHE_LINESIZE, \ .memctl_mask = \ (XCHAL_ICACHE_SIZE ? MEMCTL_IUSEWAYS_MASK : 0) | \ (XCHAL_DCACHE_SIZE ? \ diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 782f2ec62099..24eb70d619d5 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -1620,6 +1620,12 @@ static void translate_depbits(DisasContext *dc, const OpcodeArg arg[], arg[2].imm, arg[3].imm); } +static void translate_diwbuip(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_addi_i32(arg[0].out, arg[0].in, dc->config->dcache_line_bytes); +} + static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -3098,6 +3104,10 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_nop, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "diwbui.p", + .translate = translate_diwbuip, + .op_flags = XTENSA_OP_PRIVILEGED, + }, { .name = "dpfl", .translate = translate_dcache, .op_flags = XTENSA_OP_PRIVILEGED, From patchwork Tue May 14 20:44:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943739 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2851092A for ; Tue, 14 May 2019 21:00:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 198E728884 for ; Tue, 14 May 2019 21:00:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 182F32892B; Tue, 14 May 2019 21:00:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9058D28884 for ; Tue, 14 May 2019 21:00:44 +0000 (UTC) Received: from localhost ([127.0.0.1]:54079 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeXT-0001Rk-Ga for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:00:43 -0400 Received: from eggs.gnu.org ([209.51.188.92]:38999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV3-0007lo-IS for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIj-0007Yw-MZ for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:30 -0400 Received: from mail-lj1-x243.google.com ([2a00:1450:4864:20::243]:38450) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIj-0007Tz-4H for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:29 -0400 Received: by mail-lj1-x243.google.com with SMTP id 14so501763ljj.5 for ; Tue, 14 May 2019 13:45:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wQy3/F5joNergsR/ABXk05EEEem/roqnfLo8tHgTfa8=; b=aYHsbDOpRKkHD1//NPrG1MNWmGTXj4BQKpBZ5pmGn10shL69RFedWr+h1TT5qApvVP 3RLXY2/mNS4pAkNPf6Qr38+H9TU0OvJyZJm8LmsHibCRTgybKqwtxTKyf7Navx74PaPG DeTxF7CAGxNw5ZAR92oO/9gT1hN1C3H444BLnqBJWnFozmeEGX1euzxtm+bQYCa8FrbV IH6PPeskuSoPpE+sg4bB/Eu3g2rnvzjCqaI85eWKzgwOzjDlnh401JsQmnP597Odt1Z+ CIBDQa1L3xmyoKRKucL4CurLzwcXX7ga7KZE1xkLSEDEHRU5hV0Jnb2aDAUtkdMW5Trf yMGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wQy3/F5joNergsR/ABXk05EEEem/roqnfLo8tHgTfa8=; b=HzbpzzCMYmnPdRg5CmKOC6EssmS6/yRYc6BdiY3tN3AX4H402SatGZZUgbKlL0hW0X zpKlfCVD0iOmhtqsqQKe42Xo3l2M4TXM9S8Bhev/VDweOcP4REuV0it92a8TAZ1uoa4C Ke5bkiyO1rYZ+yDyAb3Sq26RrTZJBQydk3oUJilhpscXxR+eot1F8BfPm6y5EVlu2SHx Y+/oBIVOu7Seh4OnbK1AASoXv/EOM0w8EnKxx+FErtEguq1i7qBfEOIPjUkC2KBDSWMF /TvIdgFVwk9aCyNFjV8XKcFc7wzKzdrpbPNOyuPOx24VIPyhccb6pKWWaBrxFbKEPskB rVEw== X-Gm-Message-State: APjAAAUKwdHROhON031pslrn8hRjW8skXbWtu2sXKPMebwyMijBdda6b Z5TZj78QhwLA8J+l9YWmNIG57fsUsdg= X-Google-Smtp-Source: APXvYqyCHAmIqOFxvd/ykkIeYJDB2r+CsqKeDCyY6UBlgdSkd0IuS5vOISQHUwxqk23b4J3FbOppag== X-Received: by 2002:a2e:9ada:: with SMTP id p26mr17592870ljj.167.1557866722717; Tue, 14 May 2019 13:45:22 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:22 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:45 -0700 Message-Id: <20190514204447.17486-8-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::243 Subject: [Qemu-devel] [PATCH 7/9] target/xtensa: implement block prefetch option opcodes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Block prefetch option adds a bunch of non-privileged opcodes that may be implemented as nops since QEMU doesn't model caches. Signed-off-by: Max Filippov Reviewed-by: Philippe Mathieu-Daudé --- target/xtensa/translate.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 24eb70d619d5..356eb9948701 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -3078,6 +3078,9 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_dcache, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "dhi.b", + .translate = translate_nop, + }, { .name = "dhu", .translate = translate_dcache, .op_flags = XTENSA_OP_PRIVILEGED, @@ -3085,9 +3088,15 @@ static const XtensaOpcodeOps core_ops[] = { .name = "dhwb", .translate = translate_dcache, }, { + .name = "dhwb.b", + .translate = translate_nop, + }, { .name = "dhwbi", .translate = translate_dcache, }, { + .name = "dhwbi.b", + .translate = translate_nop, + }, { .name = "dii", .translate = translate_nop, .op_flags = XTENSA_OP_PRIVILEGED, @@ -3112,15 +3121,33 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_dcache, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "dpfm.b", + .translate = translate_nop, + }, { + .name = "dpfm.bf", + .translate = translate_nop, + }, { .name = "dpfr", .translate = translate_nop, }, { + .name = "dpfr.b", + .translate = translate_nop, + }, { + .name = "dpfr.bf", + .translate = translate_nop, + }, { .name = "dpfro", .translate = translate_nop, }, { .name = "dpfw", .translate = translate_nop, }, { + .name = "dpfw.b", + .translate = translate_nop, + }, { + .name = "dpfw.bf", + .translate = translate_nop, + }, { .name = "dpfwo", .translate = translate_nop, }, { @@ -3628,6 +3655,21 @@ static const XtensaOpcodeOps core_ops[] = { .par = (const uint32_t[]){true}, .op_flags = XTENSA_OP_PRIVILEGED, }, { + .name = "pfend.a", + .translate = translate_nop, + }, { + .name = "pfend.o", + .translate = translate_nop, + }, { + .name = "pfnxt.f", + .translate = translate_nop, + }, { + .name = "pfwait.a", + .translate = translate_nop, + }, { + .name = "pfwait.o", + .translate = translate_nop, + }, { .name = "pitlb", .translate = translate_ptlb, .par = (const uint32_t[]){false}, From patchwork Tue May 14 20:44:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943741 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 19C1192A for ; Tue, 14 May 2019 21:03:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF5C1287CE for ; Tue, 14 May 2019 21:03:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE6F328880; Tue, 14 May 2019 21:03:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UPPERCASE_50_75 autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 958A8287CE for ; Tue, 14 May 2019 21:03:23 +0000 (UTC) Received: from localhost ([127.0.0.1]:54120 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQea2-0003HI-LD for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:03:22 -0400 Received: from eggs.gnu.org ([209.51.188.92]:38999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV2-0007lo-HT for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIk-0007c0-QL for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:32 -0400 Received: from mail-lj1-x243.google.com ([2a00:1450:4864:20::243]:43389) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIj-0007V7-9h for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:30 -0400 Received: by mail-lj1-x243.google.com with SMTP id z5so471523lji.10 for ; Tue, 14 May 2019 13:45:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jcFS5+jIJKosDV3MzdYV6crVIuBE3kgBVMwFRGOcg+I=; b=VHsT1I4dvW74OLvRw/avbw0DjE1VWDUevQKUqF7QRLQqInjBcwg/VH55fATvo5ivvg zzn/hfWoS950q8cV7b/EkOayV/qp4PdZBQCW9QJR5LLXIXmpE0Q1WDdgeT/R2eGUplSI 3OAG5A4Zw0Si6RxndTChCe7+MwxDvVjy2y6fHP7kEkPkjRCAe5wv36rCh5JO76W/V4nW q6h4J4SanGKiOshIPHj1+eY0tcqr7kbuz8GYaazFwEkj5EIsAZSWzFRLIWuXkbvv0oTo kMnMnUfuy1x8fN2/hX2Pqw4j1rbkPyqWkAQ/rtAY5tUUUK6nDDFtB28ZVhqs4Ko6To3r /B6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jcFS5+jIJKosDV3MzdYV6crVIuBE3kgBVMwFRGOcg+I=; b=AnGRh3m2pgROvS9qpVRSG9b8S69vnpWW4+Xt3Nx9R60vfgv8Crepjo4foCaHWun/y5 Snl5KLOnB2GplCedBuFk/K80BzXY+L50qjKwQnBy7FkaF9jVnHfb1ljsKVAEX4E02MLL vBZHoOwP3f9O4qVbmUI6kglk1YhXy+5m8gMoumVV1w12TDUJh5pGZs7z4BFQuSRUX67q OPzUfpASb5KWWgqNTzF+Z+qoQj2bsUFbszSrpOfp4B5k9QwomKhIpd22EEWuZKgwoezb EjPT6zUdabZqVHWN8VNWtzNeSx14dQQi2lbNAL89X5gFYswsllo6M10OKIvXjszwn+8H o4RA== X-Gm-Message-State: APjAAAVflMlJT4EE8a3rCcbW0MBMnkgFdH0FKBlsmCqyf4C9BxT2jPZc N5b9Eh6dG+1SKQ9cH7Q0vqv8DEpPl88= X-Google-Smtp-Source: APXvYqwgwgP1I4SXag4lM6DwwTU/YV+/9bqGZtJm5cWDJmqt9q30SfeG5X547Yw0MehgHuwK74KI+Q== X-Received: by 2002:a2e:9f41:: with SMTP id v1mr13805828ljk.66.1557866724525; Tue, 14 May 2019 13:45:24 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:24 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:46 -0700 Message-Id: <20190514204447.17486-9-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::243 Subject: [Qemu-devel] [PATCH 8/9] target/xtensa: update list of exception causes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add XEA2 exception cause codes defined in recent Xtensa ISA releases. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index ba4ef2b6a729..8301923e4c4a 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -280,14 +280,15 @@ enum { LEVEL1_INTERRUPT_CAUSE, ALLOCA_CAUSE, INTEGER_DIVIDE_BY_ZERO_CAUSE, - PRIVILEGED_CAUSE = 8, + PC_VALUE_ERROR_CAUSE, + PRIVILEGED_CAUSE, LOAD_STORE_ALIGNMENT_CAUSE, - - INSTR_PIF_DATA_ERROR_CAUSE = 12, + EXTERNAL_REG_PRIVILEGE_CAUSE, + EXCLUSIVE_ERROR_CAUSE, + INSTR_PIF_DATA_ERROR_CAUSE, LOAD_STORE_PIF_DATA_ERROR_CAUSE, INSTR_PIF_ADDR_ERROR_CAUSE, LOAD_STORE_PIF_ADDR_ERROR_CAUSE, - INST_TLB_MISS_CAUSE, INST_TLB_MULTI_HIT_CAUSE, INST_FETCH_PRIVILEGE_CAUSE, From patchwork Tue May 14 20:44:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10943747 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1137392A for ; Tue, 14 May 2019 21:06:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0757287CE for ; Tue, 14 May 2019 21:06:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E2CA428868; Tue, 14 May 2019 21:06:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.5 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,HK_RANDOM_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BB13E287CE for ; Tue, 14 May 2019 21:06:02 +0000 (UTC) Received: from localhost ([127.0.0.1]:54188 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQecb-000582-SA for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 May 2019 17:06:01 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQeV2-0007lu-NN for qemu-devel@nongnu.org; Tue, 14 May 2019 16:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQeIl-0007cB-2f for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:32 -0400 Received: from mail-lf1-x144.google.com ([2a00:1450:4864:20::144]:45619) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQeIk-0007Vb-Nq for qemu-devel@nongnu.org; Tue, 14 May 2019 16:45:31 -0400 Received: by mail-lf1-x144.google.com with SMTP id n22so220195lfe.12 for ; Tue, 14 May 2019 13:45:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FXb6aboJp5Icq+FwNf9gA5rmibu3GFrNef50fwTDTPg=; b=KlkZZMZa+q+uA6Pkttf8tc6v+XK1gPv9hxxzCQCNeS1wq2HX5Nd/ARG6xPsy/jvSOs JMShqZxtLwB9cAuAaCbc/9426yH768oYn+5s/WVQzH3EoD9nq+f+L7zIGrxrN3TVPF+5 bs1tpm9lOfWGVQqP3z4rFOIJANKR1azDd2314Ys67WbWk5cedP9br/+sW9cdELEoSv35 jTfsTa/D312obWzPqzQ+mNBVPOZy3mOFpnS/JI+iXX92uGowYyzRfm/QJFuGzZaQjhQz pBYgeJJDps6Gk9ySId5pDNLwp+XFyMYkGIhRWu7/gqvi8meKoVyTv9em/17SDh2DqC6m pfvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FXb6aboJp5Icq+FwNf9gA5rmibu3GFrNef50fwTDTPg=; b=Vb4shJVnK6VqAUFxkMDFQ4KFn4/T7iQa8wmtN5zuKUY9AEYrdasXiv9BEPCxgO7Uwh AUNgxL8AmsAvDtmRGyUpFwToX1YQrSl7Ob0i3feiC6+rLUsFvX+7YqVwxdZrpZfcFncJ Qc5AKm5PKNJqXI98OqaQiuT7Y4mcJrPwd/OAlvgf35os2miMVg6ifEUIFuKm3/VyrPjI hvkut9BIVQTte5gflqkRn5Pa2CjNOLkAQFcSFuW02/rxo+eHYSPo44A8bv58CZiFLfoj YkarOo9ysI9ZS9Bif3YQgBZdqtv3i/LCnA3lOeth+BXNse5KiSeE8y2g4fKWQDaZtjo4 2oiw== X-Gm-Message-State: APjAAAXHuN4Gr9Q8a2SvVSSkGVI2YScSslCMvjK5Y0gzCB2CTriqtAC6 m/Ah7AxryFs5X/4fxJ/K8HNM55nNb5A= X-Google-Smtp-Source: APXvYqxSvg/4cQ1JhSl+358rAsvj4erFdhsGrsS/ACvQ3q0JhGTh2O9PNsETmwmcU+u4kqHGtWI6/g== X-Received: by 2002:a19:9c8f:: with SMTP id f137mr18065772lfe.94.1557866726555; Tue, 14 May 2019 13:45:26 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id 78sm4011lje.81.2019.05.14.13.45.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 May 2019 13:45:26 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Tue, 14 May 2019 13:44:47 -0700 Message-Id: <20190514204447.17486-10-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190514204447.17486-1-jcmvbkbc@gmail.com> References: <20190514204447.17486-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::144 Subject: [Qemu-devel] [PATCH 9/9] target/xtensa: implement exclusive access option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The Exclusive Instructions provide a general-purpose mechanism for atomic updates of memory-based synchronization variables that can be used for exclusion algorithms. Use cmpxchg-based implementation that is sufficient for the typical use of exclusive access in atomic operations. Signed-off-by: Max Filippov --- target/xtensa/cpu.c | 1 + target/xtensa/cpu.h | 2 + target/xtensa/helper.h | 1 + target/xtensa/op_helper.c | 42 ++++++++++++++++ target/xtensa/overlay_tool.h | 8 ++- target/xtensa/translate.c | 100 ++++++++++++++++++++++++++++++++++++++ tests/tcg/xtensa/test_exclusive.S | 48 ++++++++++++++++++ 7 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/xtensa/test_exclusive.S diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 4215a1881ec7..54c834228a91 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -82,6 +82,7 @@ static void xtensa_cpu_reset(CPUState *s) XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15; env->sregs[CONFIGID0] = env->config->configid[0]; env->sregs[CONFIGID1] = env->config->configid[1]; + env->exclusive_addr = -1; #ifndef CONFIG_USER_ONLY reset_mmu(env); diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 8301923e4c4a..28a6fb4d796d 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -527,6 +527,8 @@ typedef struct CPUXtensaState { } fregs[16]; float_status fp_status; uint32_t windowbase_next; + uint32_t exclusive_addr; + uint32_t exclusive_val; #ifndef CONFIG_USER_ONLY xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index 9216bee57e9a..8532de0b35f5 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -24,6 +24,7 @@ DEF_HELPER_1(check_interrupts, void, env) DEF_HELPER_2(intset, void, env, i32) DEF_HELPER_2(intclear, void, env, i32) DEF_HELPER_3(check_atomctl, void, env, i32, i32) +DEF_HELPER_4(check_exclusive, void, env, i32, i32, i32) DEF_HELPER_2(wsr_memctl, void, env, i32) DEF_HELPER_2(itlb_hit_test, void, env, i32) diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index 04971b044fac..09f4962d008a 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -130,6 +130,48 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr) } } +void HELPER(check_exclusive)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr, + uint32_t is_write) +{ + uint32_t paddr, page_size, access; + uint32_t atomctl = env->sregs[ATOMCTL]; + int rc = xtensa_get_physical_addr(env, true, vaddr, is_write, + xtensa_get_cring(env), &paddr, + &page_size, &access); + + if (rc) { + HELPER(exception_cause_vaddr)(env, pc, rc, vaddr); + } + + /* When data cache is not configured use ATOMCTL bypass field. */ + if (!xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) { + access = PAGE_CACHE_BYPASS; + } + + switch (access & PAGE_CACHE_MASK) { + case PAGE_CACHE_WB: + atomctl >>= 2; + /* fall through */ + case PAGE_CACHE_WT: + atomctl >>= 2; + /* fall through */ + case PAGE_CACHE_BYPASS: + if ((atomctl & 0x3) == 0) { + HELPER(exception_cause_vaddr)(env, pc, + EXCLUSIVE_ERROR_CAUSE, vaddr); + } + break; + + case PAGE_CACHE_ISOLATE: + HELPER(exception_cause_vaddr)(env, pc, + LOAD_STORE_ERROR_CAUSE, vaddr); + break; + + default: + break; + } +} + void HELPER(wsr_memctl)(CPUXtensaState *env, uint32_t v) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_ICACHE)) { diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index 4925b21f0edf..f0cc33adfe05 100644 --- a/target/xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h @@ -76,6 +76,10 @@ #define XCHAL_HAVE_MPU 0 #endif +#ifndef XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE 0 +#endif + #define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0) #define XTENSA_OPTIONS ( \ @@ -96,8 +100,8 @@ XCHAL_OPTION(XCHAL_HAVE_FP, XTENSA_OPTION_FP_COPROCESSOR) | \ XCHAL_OPTION(XCHAL_HAVE_RELEASE_SYNC, XTENSA_OPTION_MP_SYNCHRO) | \ XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \ - XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \ - XTENSA_OPTION_ATOMCTL) | \ + XCHAL_OPTION(((XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000) || \ + XCHAL_HAVE_EXCLUSIVE), XTENSA_OPTION_ATOMCTL) | \ XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \ /* Interrupts and exceptions */ \ XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \ diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 356eb9948701..158a600b4293 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -87,6 +87,8 @@ static TCGv_i32 cpu_BR8[2]; static TCGv_i32 cpu_SR[256]; static TCGv_i32 cpu_UR[256]; static TCGv_i32 cpu_windowbase_next; +static TCGv_i32 cpu_exclusive_addr; +static TCGv_i32 cpu_exclusive_val; static GHashTable *xtensa_regfile_table; @@ -216,6 +218,14 @@ void xtensa_translate_init(void) tcg_global_mem_new_i32(cpu_env, offsetof(CPUXtensaState, windowbase_next), "windowbase_next"); + cpu_exclusive_addr = + tcg_global_mem_new_i32(cpu_env, + offsetof(CPUXtensaState, exclusive_addr), + "exclusive_addr"); + cpu_exclusive_val = + tcg_global_mem_new_i32(cpu_env, + offsetof(CPUXtensaState, exclusive_val), + "exclusive_val"); } void **xtensa_get_regfile_by_name(const char *name) @@ -1592,6 +1602,12 @@ static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[], tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm)); } +static void translate_clrex(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + tcg_gen_movi_i32(cpu_exclusive_addr, -1); +} + static void translate_const16(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -1667,6 +1683,17 @@ static void translate_extui(DisasContext *dc, const OpcodeArg arg[], tcg_temp_free(tmp); } +static void translate_getex(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_extract_i32(tmp, cpu_SR[ATOMCTL], 8, 1); + tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], arg[0].in, 8, 1); + tcg_gen_mov_i32(arg[0].out, tmp); + tcg_temp_free(tmp); +} + static void translate_icache(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -1714,6 +1741,38 @@ static void translate_l32e(DisasContext *dc, const OpcodeArg arg[], tcg_temp_free(addr); } +#ifdef CONFIG_USER_ONLY +static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) +{ +} +#else +static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) +{ + if (!option_enabled(dc, XTENSA_OPTION_MPU)) { + TCGv_i32 tpc = tcg_const_i32(dc->pc); + TCGv_i32 write = tcg_const_i32(is_write); + + gen_helper_check_exclusive(cpu_env, tpc, addr, write); + tcg_temp_free(tpc); + tcg_temp_free(write); + } +} +#endif + +static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + TCGv_i32 addr = tcg_temp_new_i32(); + + tcg_gen_mov_i32(addr, arg[1].in); + gen_load_store_alignment(dc, 2, addr, true); + gen_check_exclusive(dc, addr, false); + tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->ring, MO_TEUL); + tcg_gen_mov_i32(cpu_exclusive_addr, addr); + tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out); + tcg_temp_free(addr); +} + static void translate_ldst(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -2269,6 +2328,33 @@ static void translate_s32e(DisasContext *dc, const OpcodeArg arg[], tcg_temp_free(addr); } +static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[], + const uint32_t par[]) +{ + TCGv_i32 prev = tcg_temp_new_i32(); + TCGv_i32 addr = tcg_temp_local_new_i32(); + TCGv_i32 res = tcg_temp_local_new_i32(); + TCGLabel *label = gen_new_label(); + + tcg_gen_movi_i32(res, 0); + tcg_gen_mov_i32(addr, arg[1].in); + gen_load_store_alignment(dc, 2, addr, true); + tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, label); + gen_check_exclusive(dc, addr, true); + tcg_gen_atomic_cmpxchg_i32(prev, cpu_exclusive_addr, cpu_exclusive_val, + arg[0].in, dc->cring, MO_TEUL); + tcg_gen_setcond_i32(TCG_COND_EQ, res, prev, cpu_exclusive_val); + tcg_gen_movcond_i32(TCG_COND_EQ, cpu_exclusive_val, + prev, cpu_exclusive_val, prev, cpu_exclusive_val); + tcg_gen_movi_i32(cpu_exclusive_addr, -1); + gen_set_label(label); + tcg_gen_extract_i32(arg[0].out, cpu_SR[ATOMCTL], 8, 1); + tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], res, 8, 1); + tcg_temp_free(prev); + tcg_temp_free(addr); + tcg_temp_free(res); +} + static void translate_salt(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { @@ -3068,6 +3154,9 @@ static const XtensaOpcodeOps core_ops[] = { .name = "clrb_expstate", .translate = translate_clrb_expstate, }, { + .name = "clrex", + .translate = translate_clrex, + }, { .name = "const16", .translate = translate_const16, }, { @@ -3173,6 +3262,9 @@ static const XtensaOpcodeOps core_ops[] = { .name = "extw", .translate = translate_memw, }, { + .name = "getex", + .translate = translate_getex, + }, { .name = "hwwdtlba", .op_flags = XTENSA_OP_ILL, }, { @@ -3244,6 +3336,10 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_l32e, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD, }, { + .name = "l32ex", + .translate = translate_l32ex, + .op_flags = XTENSA_OP_LOAD, + }, { .name = (const char * const[]) { "l32i", "l32i.n", NULL, }, @@ -4557,6 +4653,10 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_s32e, .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE, }, { + .name = "s32ex", + .translate = translate_s32ex, + .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, + }, { .name = (const char * const[]) { "s32i", "s32i.n", "s32nb", NULL, }, diff --git a/tests/tcg/xtensa/test_exclusive.S b/tests/tcg/xtensa/test_exclusive.S new file mode 100644 index 000000000000..7757a552ea00 --- /dev/null +++ b/tests/tcg/xtensa/test_exclusive.S @@ -0,0 +1,48 @@ +#include "macros.inc" + +test_suite exclusive + +#if XCHAL_HAVE_EXCLUSIVE + +test exclusive_nowrite + movi a2, 0x29 + wsr a2, atomctl + clrex + movi a2, 1f + movi a3, 1 + s32ex a3, a2 + getex a3 + assert eqi, a3, 0 + l32i a3, a2, 0 + assert eqi, a3, 3 + +.data +.align 4 +1: + .word 3 +.text +test_end + +test exclusive_write + movi a2, 0x29 + wsr a2, atomctl + movi a2, 1f + l32ex a3, a2 + assert eqi, a3, 3 + movi a3, 2 + s32ex a3, a2 + getex a3 + assert eqi, a3, 1 + l32i a3, a2, 0 + assert eqi, a3, 2 + +.data +.align 4 +1: + .word 3 +.text +test_end + +#endif + +test_suite_end