From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:51800) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sq2Zl-0007W6-B8 for qemu-devel@nongnu.org; Sat, 14 Jul 2012 09:40:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Sq2Zi-0005PZ-W9 for qemu-devel@nongnu.org; Sat, 14 Jul 2012 09:40:01 -0400 Received: from mail-lb0-f173.google.com ([209.85.217.173]:35254) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sq2Zi-0005PV-Ig for qemu-devel@nongnu.org; Sat, 14 Jul 2012 09:39:58 -0400 Received: by lbok6 with SMTP id k6so696035lbo.4 for ; Sat, 14 Jul 2012 06:39:57 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: <1342154108-798-1-git-send-email-proljc@gmail.com> <1342154108-798-12-git-send-email-proljc@gmail.com> Date: Sat, 14 Jul 2012 21:39:57 +0800 Message-ID: From: Jia Liu Content-Type: text/plain; charset=ISO-8859-1 Subject: Re: [Qemu-devel] [PATCH v9 11/15] target-or32: Add system instructions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Blue Swirl Cc: Max Filippov , qemu-devel@nongnu.org Hi Blue, On Sat, Jul 14, 2012 at 9:19 PM, Blue Swirl wrote: > On Sat, Jul 14, 2012 at 11:12 AM, Jia Liu wrote: >> Hi Max >> >> On Fri, Jul 13, 2012 at 5:27 PM, Max Filippov wrote: >>> On Fri, Jul 13, 2012 at 8:35 AM, Jia Liu wrote: >>>> Add OpenRISC system instructions. >>>> >>>> Signed-off-by: Jia Liu >>>> --- >>>> target-openrisc/Makefile.objs | 2 +- >>>> target-openrisc/cpu.h | 3 + >>>> target-openrisc/helper.h | 4 + >>>> target-openrisc/sys_helper.c | 287 +++++++++++++++++++++++++++++++++++++++++ >>>> target-openrisc/translate.c | 10 ++ >>>> 5 files changed, 305 insertions(+), 1 deletion(-) >>>> create mode 100644 target-openrisc/sys_helper.c >>>> >>>> diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs >>>> index 926fc2f..44dc539 100644 >>>> --- a/target-openrisc/Makefile.objs >>>> +++ b/target-openrisc/Makefile.objs >>>> @@ -1,4 +1,4 @@ >>>> obj-$(CONFIG_SOFTMMU) += machine.o >>>> obj-y += cpu.o exception.o interrupt.o mmu.o translate.o >>>> obj-y += exception_helper.o fpu_helper.o int_helper.o \ >>>> - interrupt_helper.o mmu_helper.o >>>> + interrupt_helper.o mmu_helper.o sys_helper.o >>>> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h >>>> index df07eaf..6506665 100644 >>>> --- a/target-openrisc/cpu.h >>>> +++ b/target-openrisc/cpu.h >>>> @@ -80,6 +80,9 @@ enum { >>>> (reg) |= ((v & 0x1f) << 2);\ >>>> } while (0) >>>> >>>> +/* Version Register */ >>>> +#define SPR_VR 0xFFFF003F >>>> + >>>> /* Internal flags, delay slot flag */ >>>> #define D_FLAG 1 >>>> >>>> diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h >>>> index 6eb259a..836a70b 100644 >>>> --- a/target-openrisc/helper.h >>>> +++ b/target-openrisc/helper.h >>>> @@ -63,4 +63,8 @@ DEF_HELPER_FLAGS_3(mul32, 0, tl, env, tl, tl) >>>> /* interrupt */ >>>> DEF_HELPER_FLAGS_1(rfe, 0, void, env) >>>> >>>> +/* sys */ >>>> +DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl) >>>> +DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl) >>>> + >>>> #include "def-helper.h" >>>> diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c >>>> new file mode 100644 >>>> index 0000000..7ff8e15 >>>> --- /dev/null >>>> +++ b/target-openrisc/sys_helper.c >>>> @@ -0,0 +1,287 @@ >>>> +/* >>>> + * OpenRISC system instructions helper routines >>>> + * >>>> + * Copyright (c) 2011-2012 Jia Liu >>>> + * Zhizhou Zhang >>>> + * >>>> + * This library is free software; you can redistribute it and/or >>>> + * modify it under the terms of the GNU Lesser General Public >>>> + * License as published by the Free Software Foundation; either >>>> + * version 2 of the License, or (at your option) any later version. >>>> + * >>>> + * This library is distributed in the hope that it will be useful, >>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >>>> + * Lesser General Public License for more details. >>>> + * >>>> + * You should have received a copy of the GNU Lesser General Public >>>> + * License along with this library; if not, see . >>>> + */ >>>> + >>>> +#include "cpu.h" >>>> +#include "helper.h" >>>> + >>>> +#define TO_SPR(group, number) (((group) << 11) + (number)) >>>> + >>>> +void HELPER(mtspr)(CPUOpenRISCState *env, >>>> + target_ulong ra, target_ulong rb, target_ulong offset) >>>> +{ >>>> +#ifndef CONFIG_USER_ONLY >>>> + int spr = (ra | offset); >>>> + int idx; >>>> + >>>> + OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); >>>> + >>>> + switch (spr) { >>>> + case TO_SPR(0, 0): /* VR */ >>>> + env->vr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 16): /* NPC */ >>>> + env->npc = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 17): /* SR */ >>>> + if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^ >>>> + (rb & (SR_IME | SR_DME | SR_SM))) { >>>> + tlb_flush(env, 1); >>>> + } >>>> + env->sr = rb; >>>> + env->sr |= SR_FO; /* FO is const equal to 1 */ >>>> + if (env->sr & SR_DME) { >>>> + env->tlb->cpu_openrisc_map_address_data = >>>> + &cpu_openrisc_get_phys_data; >>>> + } else { >>>> + env->tlb->cpu_openrisc_map_address_data = >>>> + &cpu_openrisc_get_phys_nommu; >>>> + } >>>> + >>>> + if (env->sr & SR_IME) { >>>> + env->tlb->cpu_openrisc_map_address_code = >>>> + &cpu_openrisc_get_phys_code; >>>> + } else { >>>> + env->tlb->cpu_openrisc_map_address_code = >>>> + &cpu_openrisc_get_phys_nommu; >>>> + } >>>> + break; >>>> + >>>> + case TO_SPR(0, 18): /* PPC */ >>>> + env->ppc = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 32): /* EPCR */ >>>> + env->epcr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 48): /* EEAR */ >>>> + env->eear = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 64): /* ESR */ >>>> + env->esr = rb; >>>> + break; >>>> + case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ >>>> + idx = spr - TO_SPR(1, 512); >>>> + if (!(rb & 1)) { >>>> + tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK); >>>> + } >>>> + env->tlb->dtlb[0][idx].mr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(1, 640); >>>> + env->tlb->dtlb[0][idx].tr = rb; >>>> + break; >>>> + case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >>>> + case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >>>> + case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >>>> + case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >>>> + case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ >>>> + case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ >>>> + break; >>>> + case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ >>>> + idx = spr - TO_SPR(2, 512); >>>> + if (!(rb & 1)) { >>>> + tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK); >>>> + } >>>> + env->tlb->itlb[0][idx].mr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(2, 640); >>>> + env->tlb->itlb[0][idx].tr = rb; >>>> + break; >>>> + case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >>>> + case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >>>> + case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >>>> + case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >>>> + case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >>>> + case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >>>> + break; >>>> + case TO_SPR(9, 0): /* PICMR */ >>>> + env->picmr |= rb; >>>> + break; >>>> + case TO_SPR(9, 2): /* PICSR */ >>>> + env->picsr &= ~rb; >>>> + break; >>>> + case TO_SPR(10, 0): /* TTMR */ >>>> + { >>>> + int ip = env->ttmr & TTMR_IP; >>>> + >>>> + if (rb & TTMR_IP) { /* Keep IP bit. */ >>>> + env->ttmr = (rb & ~TTMR_IP) + ip; >>>> + } else { /* Clear IP bit. */ >>>> + env->ttmr = rb & ~TTMR_IP; >>>> + env->interrupt_request &= ~CPU_INTERRUPT_TIMER; >>>> + } >>>> + >>>> + cpu_openrisc_count_update(cpu); >>>> + >>>> + switch (env->ttmr & TTMR_M) { >>>> + case TIMER_NONE: >>>> + cpu_openrisc_count_stop(cpu); >>>> + break; >>>> + case TIMER_INTR: >>>> + cpu_openrisc_count_start(cpu); >>>> + break; >>>> + case TIMER_SHOT: >>>> + cpu_openrisc_count_start(cpu); >>>> + break; >>>> + case TIMER_CONT: >>>> + cpu_openrisc_count_start(cpu); >>>> + break; >>>> + default: >>>> + break; >>>> + } >>>> + } >>>> + break; >>>> + >>>> + case TO_SPR(10, 1): /* TTCR */ >>>> + env->ttcr = rb; >>>> + if (env->ttmr & TIMER_NONE) { >>>> + return; >>>> + } >>>> + cpu_openrisc_count_start(cpu); >>>> + break; >>>> + default: >>>> + >>>> + break; >>>> + } >>>> +#endif >>>> +} >>>> + >>>> +target_ulong HELPER(mfspr)(CPUOpenRISCState *env, >>>> + target_ulong rd, target_ulong ra, uint32_t offset) >>>> +{ >>>> +#ifndef CONFIG_USER_ONLY >>>> + int spr = (ra | offset); >>>> + int idx; >>>> + >>>> + OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); >>>> + >>>> + switch (spr) { >>>> + case TO_SPR(0, 0): /* VR */ >>>> + return env->vr & SPR_VR; >>>> + >>>> + case TO_SPR(0, 1): /* UPR */ >>>> + return env->upr; /* TT, DM, IM, UP present */ >>>> + >>>> + case TO_SPR(0, 2): /* CPUCFGR */ >>>> + return env->cpucfgr; >>>> + >>>> + case TO_SPR(0, 3): /* DMMUCFGR */ >>>> + return env->dmmucfgr; /* 1Way, 64 entries */ >>>> + >>>> + case TO_SPR(0, 4): /* IMMUCFGR */ >>>> + return env->immucfgr; >>>> + >>>> + case TO_SPR(0, 16): /* NPC */ >>>> + return env->npc; >>>> + >>>> + case TO_SPR(0, 17): /* SR */ >>>> + return env->sr; >>>> + >>>> + case TO_SPR(0, 18): /* PPC */ >>>> + return env->ppc; >>>> + >>>> + case TO_SPR(0, 32): /* EPCR */ >>>> + return env->epcr; >>>> + >>>> + case TO_SPR(0, 48): /* EEAR */ >>>> + return env->eear; >>>> + >>>> + case TO_SPR(0, 64): /* ESR */ >>>> + return env->esr; >>>> + >>>> + case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ >>>> + idx = spr - TO_SPR(1, 512); >>>> + return env->tlb->dtlb[0][idx].mr; >>>> + >>>> + case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(1, 640); >>>> + return env->tlb->dtlb[0][idx].tr; >>>> + >>>> + case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >>>> + case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >>>> + case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >>>> + case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >>>> + case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ >>>> + case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ >>>> + break; >>>> + >>>> + case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ >>>> + idx = spr - TO_SPR(2, 512); >>>> + return env->tlb->itlb[0][idx].mr; >>>> + >>>> + case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(2, 640); >>>> + return env->tlb->itlb[0][idx].tr; >>>> + >>>> + case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >>>> + case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >>>> + case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >>>> + case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >>>> + case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >>>> + case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >>>> + break; >>>> + >>>> + case TO_SPR(9, 0): /* PICMR */ >>>> + return env->picmr; >>>> + >>>> + case TO_SPR(9, 2): /* PICSR */ >>>> + return env->picsr; >>>> + >>>> + case TO_SPR(10, 0): /* TTMR */ >>>> + return env->ttmr; >>>> + >>>> + case TO_SPR(10, 1): /* TTCR */ >>>> + cpu_openrisc_count_update(cpu); >>>> + return env->ttcr; >>>> + >>>> + default: >>>> + break; >>>> + } >>>> +#endif >>>> + >>>> +/*If we later need to add tracepoints (or debug printfs) for the return >>>> +value, it may be useful to structure the code like this: >>>> + >>>> +target_ulong ret = 0; >>>> + >>>> +switch() { >>>> +case x: >>>> + ret = y; >>>> + break; >>>> +case z: >>>> + ret = 42; >>>> + break; >>>> +... >>>> +} >>>> + >>>> +later something like trace_spr_read(ret); >>>> + >>>> +return ret;*/ >>>> + >>>> + /* for rd is passed in, if rd unchanged, just keep it back. */ >>>> + return rd; >>>> +} >>>> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c >>>> index ed25604..8069edb 100644 >>>> --- a/target-openrisc/translate.c >>>> +++ b/target-openrisc/translate.c >>>> @@ -995,10 +995,20 @@ static void dec_misc(DisasContext *dc, uint32_t insn) >>>> >>>> case 0x2d: /* l.mfspr */ >>>> LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); >>>> + { >>>> + TCGv_i32 ti = tcg_const_i32(I16); >>>> + gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); >>>> + tcg_temp_free_i32(ti); >>>> + } >>>> break; >>>> >>>> case 0x30: /* l.mtspr */ >>>> LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); >>>> + { >>>> + TCGv_i32 im = tcg_const_i32(tmp); >>>> + gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); >>>> + tcg_temp_free_i32(im); >>>> + } >>>> break; >>> >>> openrisc ISA says that l.mtspr/l.mfspr are only accessible in supervisor mode, >>> but I don't see where it is enforced. >>> >> >> Thank you for mind me, it is the new code. Is it OK? > > I don't think so, please check for example target-ppc/translate.c:4192 > on how supervisor only mfsr is handled there. > Thank you for comment, Blue. is this code OK? case 0x2d: /* l.mfspr */ LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); { #if defined(CONFIG_USER_ONLY) gen_illegal_exception(dc); #else TCGv_i32 ti = tcg_const_i32(I16); gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); tcg_temp_free_i32(ti); #endif } break; case 0x30: /* l.mtspr */ LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); { #if defined(CONFIG_USER_ONLY) gen_illegal_exception(dc); #else TCGv_i32 im = tcg_const_i32(tmp); gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); tcg_temp_free_i32(im); #endif } break; >> >> #ifndef CONFIG_USER_ONLY >> case 0x2d: /* l.mfspr */ >> LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); >> { >> TCGv_i32 ti = tcg_const_i32(I16); >> gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); >> tcg_temp_free_i32(ti); >> } >> break; >> >> case 0x30: /* l.mtspr */ >> LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); >> { >> TCGv_i32 im = tcg_const_i32(tmp); >> gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); >> tcg_temp_free_i32(im); >> } >> break; >> #endif >> >> >>> -- >>> Thanks. >>> -- Max >> >> Regards, >> Jia >> Regards, Jia