From patchwork Wed Aug 31 21:57:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 112725 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 7A8A0B6F7C for ; Thu, 1 Sep 2011 09:56:08 +1000 (EST) Received: from localhost ([::1]:45508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QytMe-0002yS-6i for incoming@patchwork.ozlabs.org; Wed, 31 Aug 2011 18:34:32 -0400 Received: from eggs.gnu.org ([140.186.70.92]:57688) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QytL6-0008Tl-Ur for qemu-devel@nongnu.org; Wed, 31 Aug 2011 18:32:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QytL5-0006oe-H8 for qemu-devel@nongnu.org; Wed, 31 Aug 2011 18:32:56 -0400 Received: from [188.134.19.124] (port=34544 helo=octofox.metropolis) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QytL5-0006fg-5D for qemu-devel@nongnu.org; Wed, 31 Aug 2011 18:32:55 -0400 Received: from octofox.metropolis (localhost [127.0.0.1]) by octofox.metropolis (8.14.5/8.14.5) with ESMTP id p7VLvoXB028646; Thu, 1 Sep 2011 01:57:50 +0400 Received: (from jcmvbkbc@localhost) by octofox.metropolis (8.14.5/8.14.5/Submit) id p7VLvnLm028645; Thu, 1 Sep 2011 01:57:49 +0400 From: Max Filippov To: qemu-devel@nongnu.org Date: Thu, 1 Sep 2011 01:57:07 +0400 Message-Id: <1314827843-28543-17-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1314827843-28543-1-git-send-email-jcmvbkbc@gmail.com> References: <1314827843-28543-1-git-send-email-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 188.134.19.124 Cc: jcmvbkbc@gmail.com Subject: [Qemu-devel] [PATCH v3 16/32] 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 ac9bbb4..939222c 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 c119fd0..83b8a04 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);