From patchwork Sat Mar 23 21:40: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: 1062610 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qqi7BneM"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44RYrt6CzFz9sSp for ; Sun, 24 Mar 2019 08:42:06 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48405 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oOy-0008Nq-OD for incoming@patchwork.ozlabs.org; Sat, 23 Mar 2019 17:42:04 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44846) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oO6-0008Hi-Ls for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7oNz-0007Fl-0L for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:10 -0400 Received: from mail-lj1-x22b.google.com ([2a00:1450:4864:20::22b]:41659) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h7oNy-0007EM-83 for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:02 -0400 Received: by mail-lj1-x22b.google.com with SMTP id k8so4750946lja.8 for ; Sat, 23 Mar 2019 14:41:02 -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=cHHoxVcngPikqdK0lGf2UMm8mO9Tp8WV0RL0Upss65I=; b=qqi7BneMsHrFovx9CS4t1MPgwbfdTxztKiGthVWirR3bzeSxwCyIzrlNE1HJW+1JR1 JSruhtUEq7W9vfutsS3Ht1Nej4oZ6L6HNn/hkYTylX5GxWxZSQI5yrCeL4FsXGztugfA jrFYEz2at/EGAmijXPjHXzoWfKC/uLouf6m9nWj+i9SEn9/oBaca5pLeaFS6QSDc+rLY tS+djA8G+L0tcZEya5HnUY88bbXjJWcskUiGHIdzUsbhjUA739/T8nKtAi4CoNrDfPk3 wBEX6uPthjdZFUU9SkNUDIzcdLh45VqNfdYlwd5PVBojxpusgNsZrdXOtt2j2n/Qy4hE 9DZg== 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=cHHoxVcngPikqdK0lGf2UMm8mO9Tp8WV0RL0Upss65I=; b=Km31MowgpAP3DOt9mVIVcwz6byguXGOn27uKcoHA26zn11On+z7Je2gP7MMW/ly5zi tGnV+eOzxqaiB5DP9ZvE+gxF/iYpe3YQMlDdXBiZ+/M/o1HAW5SLB112DnfXPe3Q5XIV GA3Qvjh9wzDDuA2agarTqTyhGy45cJOubYCo2ncorrb05DW7t7qMmEhTfc4u7jibvioT sBfsg92OHBm0H7bfYhI0tLjnmfdRvVv4RGJeFSmPwERAtSK5TnPs6y/WWHGfjQJfYF0x fnDgbag7jXpx5CyjWbr4ioWA8+yrz5LYpufMmtugsocorUBVCEWT9xa8RfZisbrrxdM5 LKMw== X-Gm-Message-State: APjAAAVcKYk5pIFiC3bdtSZ8OCI5avzfFnMsNA0guop2tfZpZC1IHyOq oz74wIxzRtrn++N57lxowhE/hs2t X-Google-Smtp-Source: APXvYqzOSz9jCpiRbWZhpE+HhYQahwApMPeWIu1zYEdqIkkOSlcN301vBnugHTFljNM5lSAUvva7aA== X-Received: by 2002:a2e:96cb:: with SMTP id d11mr2099558ljj.157.1553377259090; Sat, 23 Mar 2019 14:40:59 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net. (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w3sm1382127lji.59.2019.03.23.14.40.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 14:40:58 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Sat, 23 Mar 2019 14:40:39 -0700 Message-Id: <20190323214043.28997-2-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190323214043.28997-1-jcmvbkbc@gmail.com> References: <20190323214043.28997-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::22b Subject: [Qemu-devel] [PATCH for-4.1 1/5] 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 | 2509 +++++++++++++++++++++++++++------------------ 3 files changed, 1496 insertions(+), 1015 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 4d8152682fe1..2b3ff8371b57 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -590,6 +590,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 f4867a9b5631..4625562ff732 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -140,6 +140,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 65561d2c4972..c50f6f8d02ec 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -91,128 +91,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) { @@ -282,18 +194,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]); } } @@ -535,313 +449,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, @@ -924,9 +582,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,23 +1311,21 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f, { XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; + xtensa_isa isa = env->config->isa; int i, j; cpu_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)) { - cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i], - (j++ % 4) == 3 ? '\n' : ' '); - } - } - - cpu_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)) { - cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i], - (j++ % 4) == 3 ? '\n' : ' '); + if (regno >= 0) { + cpu_fprintf(f, "%12s=%08x%c", + xtensa_sysreg_name(isa, i), + reg[regno], + (j++ % 4) == 3 ? '\n' : ' '); } } @@ -2470,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[], @@ -2501,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[], @@ -2776,55 +2458,291 @@ 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[] = { - { - .name = "abs", - .translate = translate_abs, +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, }, { .name = (const char * const[]) { "add", "add.n", NULL, @@ -3764,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", @@ -4372,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 | @@ -4673,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 | @@ -4682,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", @@ -4850,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, }, { @@ -4871,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 Sat Mar 23 21:40: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: 1062611 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kMtNJPYO"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44RYtr0Y6Mz9sSq for ; Sun, 24 Mar 2019 08:43:47 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48415 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oQa-0001Dk-MI for incoming@patchwork.ozlabs.org; Sat, 23 Mar 2019 17:43:44 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44812) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oO0-0008BQ-R6 for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7oNz-0007Fz-5x for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:04 -0400 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]:47041) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h7oNy-0007Ej-Pf for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:03 -0400 Received: by mail-lf1-x141.google.com with SMTP id r25so3567243lfn.13 for ; Sat, 23 Mar 2019 14:41:02 -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=RhGFjDoF8SmAA3oGW/JV0tkJokC4PfWxYKrtM6jgp3E=; b=kMtNJPYOtBB9dRm/qbvuOfzl53VHkZp2kiHwhvK8mZ525Z1k6iJXF0H2DiHljrGpBr wtUQUsn602Wdt+0f5Lm6irJyiBTtuBmvTCKluTjKw1YkzuECqDGp922jqbfOE5hGvaZI Ah6efJpx+Ya7StmIC+UC2FlltZlS4KluoXTNugxalVO5anHKGT87z4DXrhRdnHCo76UC T3w0PMXhUUWaKOjximOuC70HqEyLkA/fwcan4Yuoj5op7UnfmwCxSDQzCypsR1zQUCCI 2VlO1vPRS2MhlSAjKiep2epIwmTt2/IoGDE0njrB4ynXQZ+h2tf0dVNCdYal+Ic65Njr JKIQ== 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=RhGFjDoF8SmAA3oGW/JV0tkJokC4PfWxYKrtM6jgp3E=; b=XS0aq90E6qVHmHkN1b3MlZGFlOCjbii2esBNHjoPlhC81GhGxchNvhj+br3AQc24xK p0CtvXINQjKJFlNIvqYH/eTGgxmrgbwJX2AzIbjqB5QEswryqb8Z1+Jp5qyl8XHD1drf NjKxSoeG9qHN5Mh+4vgKlnu+tMI04yvaDOGF7FaXCu8rScpXhonk7rvHNi8CKpSUSTgI hs7llmMEUoF79GG7aV7syGahNSa5Iqc5l+6/La7CtoQw+anys8XXgA+f8O5j9L8AQOwJ Vs0kBvSgL9mbXDEpPRQxlGX+BW/aNdpRmgGa3qI9srSa6SEDjgVNwwddOAtrWFslTj5v zJYg== X-Gm-Message-State: APjAAAVdWUwLrM/osrg41bYSjXl7MVx8/sJ7G13IZIYOGT5sdP+z8jy6 ROuNgMSSyAvDH10/Egj2SErZwEEt X-Google-Smtp-Source: APXvYqx8T1oEBFdIDQ6XNMz8dnzMDOZcxbE99gcnQbW1Iosl7/0YebSVvD+xioliK9JhJlnbh6dYMQ== X-Received: by 2002:a19:9e0d:: with SMTP id h13mr8177247lfe.51.1553377261207; Sat, 23 Mar 2019 14:41:01 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net. (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w3sm1382127lji.59.2019.03.23.14.40.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 14:41:00 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Sat, 23 Mar 2019 14:40:40 -0700 Message-Id: <20190323214043.28997-3-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190323214043.28997-1-jcmvbkbc@gmail.com> References: <20190323214043.28997-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 for-4.1 2/5] 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 2b3ff8371b57..d0ca4f8b0148 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -659,17 +659,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); @@ -680,14 +669,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 2096fbbd9fc2..955bd515261c 100644 --- a/target/xtensa/mmu_helper.c +++ b/target/xtensa/mmu_helper.c @@ -77,8 +77,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 ? @@ -144,8 +144,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 : @@ -212,6 +213,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) { @@ -226,65 +235,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); @@ -292,8 +246,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); @@ -321,15 +276,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); @@ -461,8 +407,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; @@ -494,6 +441,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 Sat Mar 23 21:40: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: 1062609 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="EuSLpvuM"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44RYrT4jV3z9sSq for ; Sun, 24 Mar 2019 08:41:45 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48403 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oOd-0008G0-Ih for incoming@patchwork.ozlabs.org; Sat, 23 Mar 2019 17:41:43 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44818) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oO1-0008Bt-MI for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7oO0-0007H7-OH for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:05 -0400 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:46113) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h7oO0-0007GM-FC for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:04 -0400 Received: by mail-lj1-x242.google.com with SMTP id z26so4704656lja.13 for ; Sat, 23 Mar 2019 14:41:04 -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=QBldiYOXlgDoN/gdig7ng+lUa7qhxBo//Pip9BahW78=; b=EuSLpvuM6Cc8xy28ESaQ3eeRUbfOhLfrslqlNVD6A6X5itpLHenXC2pvKFf6n5bbE9 7VZOaQ7DoJ3YFciWC4dzRmUL3JJhOx36Ua6dRM2BWkWR4GZjgcuK70nlyijzyFH+roaW XjugvCUJwXPII9eCbRVqCjsHQ4jOBaGAiM5YywnPpgBllPw2hRW37bTQlGrDNnRDuTsa lVIzSfV43I4SENEOujBPN6Urq+lj9cZLPbRaQkmFlTSMN8vmhA3yUk6z0ydJKP/Xuv+J +A6WIu6d694Xefv7zjz3fDEjgEBF1XY8A2wBbqQ/9Y3drswuKMZpOquptbowaI7oCBn0 3cIg== 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=QBldiYOXlgDoN/gdig7ng+lUa7qhxBo//Pip9BahW78=; b=f1prAHxE2Qfu/9jIHKdl6omOWBJCR+zLyoe7hkQ//2wKBOOQFPV/6Ylm9PYuyGVzZ9 LTunjkt1qeaKy4Stg/ykt2N8WoPH4SDEVoG2OWOLooOz++0EdGLvFVZ442icwrGJ3xji Gci96F6iE/gz4a72sqYxmmjyi9fDjbCD3OgAjd67y0hMkb3p5g9/DwytP96AyHkfuWsB Iec27En+QB74n2WA62UJWRpy9PRE8M93tBCZbM4r2iWncVWOhfhYLAOZcMNo1ga9WLDl T+dqeh+2i9E6mP3GGIzZmUz5EVnQU4zQwORFOBXb6Vjc775FoXYFmI6Y4tsciHqD+6tW xXPg== X-Gm-Message-State: APjAAAXHMn7YkwKos6x8Vb/ZQdKuII5uR2tYBjJs+ayz9B5TrbqE7oBr Ihrqa8s8oGJJrtBSm3YXKAOrYbEt X-Google-Smtp-Source: APXvYqx0sHnuXf4S0gLy6ueegz+KHRrDCSjnNeNJE6ZrjId6zwORaobgVyEgQpihTJVPv606IA4/og== X-Received: by 2002:a2e:85d2:: with SMTP id h18mr8571545ljj.128.1553377263130; Sat, 23 Mar 2019 14:41:03 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net. (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w3sm1382127lji.59.2019.03.23.14.41.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 14:41:02 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Sat, 23 Mar 2019 14:40:41 -0700 Message-Id: <20190323214043.28997-4-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190323214043.28997-1-jcmvbkbc@gmail.com> References: <20190323214043.28997-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 for-4.1 3/5] 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 d0ca4f8b0148..e43dfb8447e4 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 Sat Mar 23 21:40: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: 1062619 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PhiSY4TR"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44RYwm6lj7z9sSt for ; Sun, 24 Mar 2019 08:45:28 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oSF-00033S-0d for incoming@patchwork.ozlabs.org; Sat, 23 Mar 2019 17:45:27 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44834) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oO4-0008FP-2D for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7oO2-0007QE-QA for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:08 -0400 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:42813) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h7oO2-0007Jd-FL for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:06 -0400 Received: by mail-lj1-x242.google.com with SMTP id v22so4749378lje.9 for ; Sat, 23 Mar 2019 14:41:06 -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=KzOwyRtlhOKTMNSgGwqHzwDMnwqXpPYvFQdOwoJSSOY=; b=PhiSY4TRvSrNsUJnZLA87xJOWOZT5TaQshUPbbrgXJZOQXgvpQq8WWu/ApTPyt+mck 5nHjWBYVTM6giw+WPmYMg8XeG02Iw9gVh28PiWP9+55crEB2PnP3pLw2B4IUWqG8ZgrO EVwU9eHzbauj4z3QZe17WPCJmKDju2LgGDBfCEYrdb5xJaUar04MRVYoH6MJwdjUh/C8 ZI53zAObmYluwZk1WzudSVHa/i6MeRu2jpI021DpTAU3OCt9ultNfWqATK7VfSvJRpDu 1p9gNZECCZgD65QlLNENvWlcT5bNXSAUiB9gIwGNvjqRnXnbrSO7oeA4yVywOrbSavYW QjGw== 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=KzOwyRtlhOKTMNSgGwqHzwDMnwqXpPYvFQdOwoJSSOY=; b=a3lf4IRYj9ruQiGpT0Drw9u4PK06b0jq5Jb69HDbw/IjJtOloC725eOfxZfKjAI3EJ Kb3hWMSUj36ofehgCmBz89LE19mLoZJQDOo2vE4I1h5exEBnnETnOlQ74w7PCxodErFh cziSTSo4K3Jyyab3n+G6k8A4TVaTy1GIgVec3GEjfECYNlMqP5AsM4zfL80G1pT66yw9 tYEoEp5fwpCF2y9eBgylYXa/fkctFFu8h8cl+AinveGI11QNkZ5B0cHr+p5RH2+2RnyN AnMi1+kbvWdZkjxNTeFfyf5I0RDQrX2NsG7FhPj74GNO7BJqo28m3VO0AAsJsKtklCt3 4cuw== X-Gm-Message-State: APjAAAUrhzQHvzNwTYueJ3byQ0FaPjylX1BrMNiFp/ToOqn6IONA4Llx qjQWI8xb6QOPmVr3FmN84T2CV82TuU8= X-Google-Smtp-Source: APXvYqy2dE8suNV+PuaFo1ENL5CayiHIaeA28NblVw3K0VwUtvLIaQwCUr9R4jpnY7JZxkqoLhIuow== X-Received: by 2002:a2e:91cb:: with SMTP id u11mr3612066ljg.64.1553377265146; Sat, 23 Mar 2019 14:41:05 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net. (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w3sm1382127lji.59.2019.03.23.14.41.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 14:41:04 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Sat, 23 Mar 2019 14:40:42 -0700 Message-Id: <20190323214043.28997-5-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190323214043.28997-1-jcmvbkbc@gmail.com> References: <20190323214043.28997-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 for-4.1 4/5] 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 e43dfb8447e4..549f34e43092 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 c50f6f8d02ec..40c8934f9cc1 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 Sat Mar 23 21:40: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: 1062612 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="k8haZEzD"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44RYv535hYz9sSq for ; Sun, 24 Mar 2019 08:44:01 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oQp-0001Qk-6f for incoming@patchwork.ozlabs.org; Sat, 23 Mar 2019 17:43:59 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7oO8-0008Ir-9j for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7oO5-0007Zm-Jd for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:12 -0400 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]:33475) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h7oO5-0007X6-3y for qemu-devel@nongnu.org; Sat, 23 Mar 2019 17:41:09 -0400 Received: by mail-lf1-x141.google.com with SMTP id v14so3679527lfi.0 for ; Sat, 23 Mar 2019 14:41:09 -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=3VHKRS2pFyTF9egBsD8AW8oCaIEEIJVbjuYY8KqSWAk=; b=k8haZEzDW3YWJJxRocJUrzhqQ68JZz5GmtC0j0TTXTwxl3fiGMa9WZ+mXrAE6HMyRm sXJp5LRQqbysJXWMpzAe9wWkNxjW7Ae2ItGP+SqAU7zYYB8PGFmzkw9peR1R30FHCXTq JTIItY/JlZN/HWU6eMevAEq8RtVscao8lq4DkE9bBwtW+K92zoLVGMu7ZkF2adDekE12 1wy2aVEWEWzrMKexepWqR2KdxzJwiMfI9neFpLy5qza+3E+vNnx1+QmiI2DgsYQ+OT4J Pw6Vc3BmSX/KeeiHCIMefx/ZrDnw1lKUoijY2nYy6oQiiLYScpWdRpo/zhN8Cz5dSu0v M59w== 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=3VHKRS2pFyTF9egBsD8AW8oCaIEEIJVbjuYY8KqSWAk=; b=BjovuMQJms7u24pQaqyjojisGUc1Eo4EwWHmFthYL90NVqGe+6Rm9DxHB+gbvXca+L NkQKRJl040Ld14Pgu+lvPPdPu1NtOYpHpIsGqboGwXVxYL+mjjDpR5YcW3EFZBVimPzc oJtE9pcdg9hy/k7x24ea9e8cfp5KWDYqmOC29JYOcaNXzzTEnR2CKNc/buMV9ravWy1/ MIN8Ovp9i9ru/ADFC6A2BS+3lQkvEhXtSANH0xYraqTcxSmlHQN8ZJfuNUVq5j/sQhX1 yltCWdtez7A5gshsriN1YAMBhvGYDXfWeGiHWcNbbTckKo72zTkdqUtMyI6sN5Zwrvvh LUQA== X-Gm-Message-State: APjAAAWnOJ1DEPjOKahPPWInnDw5ovBApXXMDJ6AyUYYkshixODn+5Tc qhuEBC5SH85HiUMprWGdFy9nmtDKp4U= X-Google-Smtp-Source: APXvYqzH3pUtb+0tIbCYY0k3CrjrNLoH5TptsdMek86Q3SPryMqN7ORUkGLF8ygKZ5wx+6n36+Wm3w== X-Received: by 2002:ac2:5471:: with SMTP id e17mr8429832lfn.87.1553377267460; Sat, 23 Mar 2019 14:41:07 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net. (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w3sm1382127lji.59.2019.03.23.14.41.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 14:41:06 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Sat, 23 Mar 2019 14:40:43 -0700 Message-Id: <20190323214043.28997-6-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190323214043.28997-1-jcmvbkbc@gmail.com> References: <20190323214043.28997-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 for-4.1 5/5] 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 | 377 +++++++++++++++++++++++++++++++++++++++++++ target/xtensa/overlay_tool.h | 29 ++++ target/xtensa/translate.c | 146 +++++++++++++++++ 6 files changed, 574 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 549f34e43092..dfbb13539231 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 955bd515261c..214601436302 100644 --- a/target/xtensa/mmu_helper.c +++ b/target/xtensa/mmu_helper.c @@ -34,6 +34,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) { /* @@ -381,7 +406,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); } @@ -578,6 +616,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) { @@ -722,6 +903,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. @@ -742,6 +1046,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; @@ -812,6 +1119,69 @@ static void dump_tlb(FILE *f, fprintf_function cpu_fprintf, } } +static void dump_mpu(FILE *f, fprintf_function cpu_fprintf, + CPUXtensaState *env, + const xtensa_mpu_entry *entry, unsigned n) +{ + unsigned i; + + cpu_fprintf(f, + "\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) ? '-' : ' '; + + cpu_fprintf(f, + "\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: + cpu_fprintf(f, + "Device %cB %3s\n", + (type & XTENSA_MPU_TYPE_B) ? ' ' : 'n', + (type & XTENSA_MPU_TYPE_INT) ? "int" : ""); + break; + case XTENSA_MPU_SYSTEM_TYPE_NC: + cpu_fprintf(f, + "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: + cpu_fprintf(f, + "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: + cpu_fprintf(f, "Unknown\n"); + break; + } + } +} + void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env) { if (xtensa_option_bits_enabled(env->config, @@ -823,6 +1193,13 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env) dump_tlb(f, cpu_fprintf, env, false); cpu_fprintf(f, "\nDTLB:\n"); dump_tlb(f, cpu_fprintf, env, true); + } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { + cpu_fprintf(f, "Foreground map:\n"); + dump_mpu(f, cpu_fprintf, env, + env->mpu_fg, env->config->n_mpu_fg_segments); + cpu_fprintf(f, "\nBackground map:\n"); + dump_mpu(f, cpu_fprintf, NULL, + env->config->mpu_bg, env->config->n_mpu_bg_segments); } else { cpu_fprintf(f, "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 40c8934f9cc1..4737b167f543 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},