From patchwork Wed Dec 5 03:15:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 203777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 42D2F2C0085 for ; Wed, 5 Dec 2012 14:16:12 +1100 (EST) Received: from localhost ([::1]:50047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tg5T0-0006ZQ-5o for incoming@patchwork.ozlabs.org; Tue, 04 Dec 2012 22:16:10 -0500 Received: from eggs.gnu.org ([208.118.235.92]:60601) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tg5Se-0006Oo-P2 for qemu-devel@nongnu.org; Tue, 04 Dec 2012 22:15:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tg5Sd-00028G-3F for qemu-devel@nongnu.org; Tue, 04 Dec 2012 22:15:48 -0500 Received: from mail-lb0-f173.google.com ([209.85.217.173]:49118) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tg5Sc-00023c-SQ for qemu-devel@nongnu.org; Tue, 04 Dec 2012 22:15:47 -0500 Received: by mail-lb0-f173.google.com with SMTP id c1so3561511lbg.4 for ; Tue, 04 Dec 2012 19:15:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=Or7aT2p0E0/ErX1nNd3dtXf0H5AHcFSaKsYlo4910O4=; b=dvNb4hRC2ggi7+zMdXas44CXl0Y2q+TUVerJ++JXPDXGH1+ydPCPb+6/lf/Uc5n3lH qYaHyqUpXCNq620VpFuvUSEfw7yfympFu1GFaBpKO+ibv2n2ARL7JOfxghaVX0L9seY2 plZQ/xF8RcxXSgJ56tM/Qw9kwf2598Gbyr4eUb+LL8Q2G7+CgAYsKdeI+ZweP6xu7tW0 tOce1+SxVSpIvZbPiel6QTSKuz06TVdYoxUr9dIVPy/Yqv8lJDXvCbEQ+fp/iBlE9Adr DkLCbJVSg71s9IdhRvhMquvO9yc6/PQw86HuasXssn89ydQSYni0VNerikVi/IfMu97s P4KA== Received: by 10.152.124.226 with SMTP id ml2mr1606362lab.46.1354677346471; Tue, 04 Dec 2012 19:15:46 -0800 (PST) Received: from octofox.metropolis ([188.134.19.124]) by mx.google.com with ESMTPS id er8sm1475005lbb.9.2012.12.04.19.15.45 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 04 Dec 2012 19:15:45 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 5 Dec 2012 07:15:23 +0400 Message-Id: <1354677327-22552-5-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1354677327-22552-1-git-send-email-jcmvbkbc@gmail.com> References: <1354677327-22552-1-git-send-email-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.217.173 Cc: Blue Swirl , Max Filippov Subject: [Qemu-devel] [PATCH 4/8] target-xtensa: better control rsr/wsr/xsr access to SRs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There are read-only (DEBUGCAUSE, PRID) and write-only (INTCLEAR) SRs, and INTERRUPT/INTSET SR allows rsr/wsr, but not xsr. Raise illeagal opcode exception on illegal access to these SRs. Signed-off-by: Max Filippov --- target-xtensa/translate.c | 49 +++++++++++++++++++++++++++----------------- 1 files changed, 30 insertions(+), 19 deletions(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 5416aff..fbeac7f 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -81,16 +81,27 @@ static TCGv_i32 cpu_UR[256]; 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(regname, opt) { \ +#define XTENSA_REG_ACCESS(regname, opt, acc) { \ .name = (regname), \ .opt_bits = XTENSA_OPTION_BIT(opt), \ + .access = (acc), \ } +#define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX) + #define XTENSA_REG_BITS(regname, opt) { \ .name = (regname), \ .opt_bits = (opt), \ + .access = SR_RWX, \ } static const XtensaReg sregnames[256] = { @@ -151,15 +162,15 @@ static const XtensaReg sregnames[256] = { [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR), - [INTSET] = XTENSA_REG("INTSET", XTENSA_OPTION_INTERRUPT), - [INTCLEAR] = XTENSA_REG("INTCLEAR", XTENSA_OPTION_INTERRUPT), + [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("DEBUGCAUSE", XTENSA_OPTION_DEBUG), + [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R), [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT), - [PRID] = XTENSA_REG("PRID", XTENSA_OPTION_PROCESSOR_ID), + [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), @@ -476,7 +487,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond, tcg_temp_free(tmp); } -static void gen_check_sr(DisasContext *dc, uint32_t sr) +static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) { if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) { if (sregnames[sr].name) { @@ -485,6 +496,16 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr) qemu_log("SR %d is not implemented\n", sr); } gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); + } 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("SR %s is not available for %s\n", sregnames[sr].name, + access_text[access]); + gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); } } @@ -679,14 +700,6 @@ static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) gen_jumpi_check_loop_end(dc, -1); } -static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ -} - -static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v) -{ -} - static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v) { if (dc->icount) { @@ -744,8 +757,6 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [INTCLEAR] = gen_wsr_intclear, [INTENABLE] = gen_wsr_intenable, [PS] = gen_wsr_ps, - [DEBUGCAUSE] = gen_wsr_debugcause, - [PRID] = gen_wsr_prid, [ICOUNT] = gen_wsr_icount, [ICOUNTLEVEL] = gen_wsr_icountlevel, [CCOMPARE] = gen_wsr_ccompare, @@ -1467,7 +1478,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) case 6: /*XSR*/ { TCGv_i32 tmp = tcg_temp_new_i32(); - gen_check_sr(dc, RSR_SR); + gen_check_sr(dc, RSR_SR, SR_X); if (RSR_SR >= 64) { gen_check_privilege(dc); } @@ -1698,7 +1709,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) case 3: /*RST3*/ switch (OP2) { case 0: /*RSR*/ - gen_check_sr(dc, RSR_SR); + gen_check_sr(dc, RSR_SR, SR_R); if (RSR_SR >= 64) { gen_check_privilege(dc); } @@ -1707,7 +1718,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) break; case 1: /*WSR*/ - gen_check_sr(dc, RSR_SR); + gen_check_sr(dc, RSR_SR, SR_W); if (RSR_SR >= 64) { gen_check_privilege(dc); }