From patchwork Sun Jul 24 17:10:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 106545 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B0628B6F75 for ; Mon, 25 Jul 2011 03:52:50 +1000 (EST) Received: from localhost ([::1]:49509 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2F0-0004yM-Ap for incoming@patchwork.ozlabs.org; Sun, 24 Jul 2011 13:13:22 -0400 Received: from eggs.gnu.org ([140.186.70.92]:57571) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Ec-00043U-Jo for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:13:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ql2Eb-0005Jt-Bg for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:12:58 -0400 Received: from mail-fx0-f47.google.com ([209.85.161.47]:56785) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Eb-0004u6-3T for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:12:57 -0400 Received: by mail-fx0-f47.google.com with SMTP id 11so8353846fxg.34 for ; Sun, 24 Jul 2011 10:12:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=tVeqlZB3tCnxb2dWNcYvTxCB4iiH3hC5LkKLAacasCk=; b=IVp6ZQoGZHVOSpWFIxnXVJ3/THS//fH3HLA7jhlnZGdvwTXt2C6p7ykGqFNQAenWwm nvKB4EI5RCQslWcrQNcDeTPwFPnEnC7nH7o+gh48P+GX6GD8xgnTAMZa1xNehibozKiF nbGbvgkiGmNX9BBruGuo3UkDWbyBfFYFjeaLI= Received: by 10.205.65.198 with SMTP id xn6mr1084782bkb.359.1311527576665; Sun, 24 Jul 2011 10:12:56 -0700 (PDT) Received: from octofox.metropolis ([188.134.19.124]) by mx.google.com with ESMTPS id s2sm1071918bkd.22.2011.07.24.10.12.54 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 24 Jul 2011 10:12:56 -0700 (PDT) Received: by octofox.metropolis (sSMTP sendmail emulation); Sun, 24 Jul 2011 21:12:53 +0400 From: Max Filippov To: qemu-devel@nongnu.org Date: Sun, 24 Jul 2011 21:10:54 +0400 Message-Id: <1311527469-12963-17-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> References: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.47 Cc: jcmvbkbc@gmail.com Subject: [Qemu-devel] [PATCH v2 16/31] target-xtensa: add PS register and access control 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 Signed-off-by: Max Filippov --- target-xtensa/cpu.h | 53 ++++++++++++++++++++++++++++++++++++++++++++- target-xtensa/helper.c | 1 + target-xtensa/translate.c | 29 ++++++++++++++++++++---- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 5a3b40e..a5f62b2 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -108,8 +108,27 @@ enum { enum { SAR = 3, SCOMPARE1 = 12, + PS = 230, }; +#define PS_INTLEVEL 0xf +#define PS_INTLEVEL_SHIFT 0 + +#define PS_EXCM 0x10 +#define PS_UM 0x20 + +#define PS_RING 0xc0 +#define PS_RING_SHIFT 6 + +#define PS_OWB 0xf00 +#define PS_OWB_SHIFT 8 + +#define PS_CALLINC 0x30000 +#define PS_CALLINC_SHIFT 16 +#define PS_CALLINC_LEN 2 + +#define PS_WOE 0x40000 + typedef struct XtensaConfig { const char *name; uint64_t options; @@ -145,17 +164,49 @@ static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt) return (config->options & XTENSA_OPTION_BIT(opt)) != 0; } +static inline int xtensa_get_ring(const CPUState *env) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { + return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT; + } else { + return 0; + } +} + +static inline int xtensa_get_cring(const CPUState *env) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) && + (env->sregs[PS] & PS_EXCM) == 0) { + return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT; + } else { + return 0; + } +} + +/* MMU modes definitions */ +#define MMU_MODE0_SUFFIX _ring0 +#define MMU_MODE1_SUFFIX _ring1 +#define MMU_MODE2_SUFFIX _ring2 +#define MMU_MODE3_SUFFIX _ring3 + static inline int cpu_mmu_index(CPUState *env) { - return 0; + return xtensa_get_cring(env); } +#define XTENSA_TBFLAG_RING_MASK 0x3 +#define XTENSA_TBFLAG_EXCM 0x4 + static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { *pc = env->pc; *cs_base = 0; *flags = 0; + *flags |= xtensa_get_ring(env); + if (env->sregs[PS] & PS_EXCM) { + *flags |= XTENSA_TBFLAG_EXCM; + } } #include "cpu-all.h" diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index c6ffcc9..bc186af 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -37,6 +37,7 @@ void cpu_reset(CPUXtensaState *env) { env->pc = 0; + env->sregs[PS] = 0x1f; } static const XtensaConfig core_config[] = { diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 83ac611..729002b 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -45,6 +45,8 @@ typedef struct DisasContext { TranslationBlock *tb; uint32_t pc; uint32_t next_pc; + int cring; + int ring; int is_jmp; int singlestep_enabled; @@ -65,6 +67,7 @@ static TCGv_i32 cpu_UR[256]; static const char * const sregnames[256] = { [SAR] = "SAR", [SCOMPARE1] = "SCOMPARE1", + [PS] = "PS", }; static const char * const uregnames[256] = { @@ -239,11 +242,25 @@ static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s) dc->sar_m32_5bit = false; } +static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) +{ + 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[sr], v, mask); + /* This can change mmu index, so exit tb */ + gen_jumpi(dc, dc->next_pc, -1); +} + 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, + [PS] = gen_wsr_ps, }; if (sregnames[sr]) { @@ -973,7 +990,7 @@ static void disas_xtensa_insn(DisasContext *dc) /* no ext L32R */ - tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, 0); + tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring); tcg_temp_free(tmp); } break; @@ -982,7 +999,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_load_store(type, shift) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \ - tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, 0); \ + tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ tcg_temp_free(addr); \ } while (0) @@ -1140,11 +1157,11 @@ static void disas_xtensa_insn(DisasContext *dc) tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]); tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); - tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, 0); + tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring); tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T], cpu_SR[SCOMPARE1], label); - tcg_gen_qemu_st32(tmp, addr, 0); + tcg_gen_qemu_st32(tmp, addr, dc->cring); gen_set_label(label); tcg_temp_free(addr); @@ -1345,7 +1362,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_narrow_load_store(type) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \ - tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, 0); \ + tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \ tcg_temp_free(addr); \ } while (0) @@ -1468,6 +1485,8 @@ static void gen_intermediate_code_internal( dc.singlestep_enabled = env->singlestep_enabled; dc.tb = tb; dc.pc = pc_start; + dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK; + dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring; dc.is_jmp = DISAS_NEXT; init_sar_tracker(&dc);