From nobody Sun Feb 8 09:22:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493594367998962.1366620527962; Sun, 30 Apr 2017 16:19:27 -0700 (PDT) Received: from localhost ([::1]:46196 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d4y7i-0004ww-8i for importer@patchew.org; Sun, 30 Apr 2017 19:19:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60466) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d4y3c-00025f-Fr for qemu-devel@nongnu.org; Sun, 30 Apr 2017 19:15:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d4y3Y-0006dX-Fn for qemu-devel@nongnu.org; Sun, 30 Apr 2017 19:15:12 -0400 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]:34179) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d4y3Y-0006bn-6u for qemu-devel@nongnu.org; Sun, 30 Apr 2017 19:15:08 -0400 Received: by mail-pf0-x244.google.com with SMTP id g23so25781588pfj.1 for ; Sun, 30 Apr 2017 16:15:08 -0700 (PDT) Received: from localhost (z209.124-44-183.ppp.wakwak.ne.jp. [124.44.183.209]) by smtp.gmail.com with ESMTPSA id v12sm19716877pgn.5.2017.04.30.16.15.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 30 Apr 2017 16:15: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 :in-reply-to:references; bh=uQCmnDtG3uspUhC/VPCTOH7VGCqVDNRqZ8bLg6VY2P8=; b=IeXxf+KFJvAOhWm+Uy7K49C/BW67L82C1IC2vuL78i0P5zP1wEtv4FhNjloFYaerjn Any7gPEIOSlIwmMgPaUEW0S9ozzwaI1nvyG2z37UAhDoLgHFitgr83VH4PLtp+CJkEKl jC93HPvdJ8f5L3wh5gWw4vI1L+3SlZGYKPWhwIX+b0f2cKzomJzo57W5hdaz8Bi6NG5Z 1dOohZs/4DsdiFi3tipTw7ZpVR1sB8pQhMI2vrxUebMW0nM+0Mu7vM0+rU2/UbhZo7V9 PLKLALCaFx3IAQ+Zi8qX5lc9JfRoWyGtMF19JudWRV4Sk8F+IJ3sPSLkqoDDNmOUXOok lTjQ== 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:in-reply-to:references; bh=uQCmnDtG3uspUhC/VPCTOH7VGCqVDNRqZ8bLg6VY2P8=; b=WuUNR1jlboB71KdsY6HTQ8SjWZ81DsoK1WwYr1V560C6QVkR/aco3dXp22TjEx0qb8 aC9R+XRcxqfCaET8vriPAMr+MkOKNsoR5P6wwnSqgs9Cw3lJhFGgeHoJrd8O34U3nMqf v5yUeKrE2IQMNq94rFA5ChcvbYA6zoI9JE0Us37csbyTTPBRAIORe/zkaLF+XN3fGP02 uAG28tOyfz22AJO2upeQldLAL4YttoEBYdhCl5nbRWCik/xIJu8m+xNsN4qUTGRWCApG Mwoq5HbjzbCrT+Y0BJ626WbeBBAMHvdpybzbjUf6Rcxi7Dw4LbpkYZ1s/jddR/8z/7nl 6XGw== X-Gm-Message-State: AN3rC/4+eVYcYWtd51Nn6+btemhbZmGHd3U19tVC4YRxMXf84iJ/ngKq XwLW/jdJLZN7uA== X-Received: by 10.98.197.194 with SMTP id j185mr23002338pfg.239.1493594107320; Sun, 30 Apr 2017 16:15:07 -0700 (PDT) From: Stafford Horne To: peter.maydell@linaro.org Date: Mon, 1 May 2017 08:14:21 +0900 Message-Id: <954c36a45feb9e2a8fac76ef2866b734d8eac91f.1493593744.git.shorne@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::244 Subject: [Qemu-devel] [PULL 07/11] target/openrisc: implement shadow registers 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: Stafford Horne , QEMU Development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Shadow registers are part of the openrisc spec along with sr[cid], as part of the fast context switching feature. When exceptions occur, instead of having to save registers to the stack if enabled the CID will increment and a new set of registers will be available. This patch only implements shadow registers which can be used as extra scratch registers via the mfspr and mtspr if required. This is implemented in a way where it would be easy to add on the fast context switching, currently cid is hardcoded to 0. This is need for openrisc linux smp kernels to boot correctly. Signed-off-by: Stafford Horne --- linux-user/elfload.c | 2 +- linux-user/main.c | 18 +++++++++--------- linux-user/openrisc/target_cpu.h | 6 +++--- linux-user/openrisc/target_signal.h | 2 +- linux-user/signal.c | 16 ++++++++-------- target/openrisc/cpu.c | 4 +++- target/openrisc/cpu.h | 15 +++++++++++++-- target/openrisc/gdbstub.c | 4 ++-- target/openrisc/machine.c | 6 +++--- target/openrisc/sys_helper.c | 9 +++++++++ target/openrisc/translate.c | 5 +++-- 11 files changed, 55 insertions(+), 32 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index f520d77..ce77317 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1052,7 +1052,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *= regs, int i; =20 for (i =3D 0; i < 32; i++) { - (*regs)[i] =3D tswapreg(env->gpr[i]); + (*regs)[i] =3D tswapreg(cpu_get_gpr(env, i)); } (*regs)[32] =3D tswapreg(env->pc); (*regs)[33] =3D tswapreg(cpu_get_sr(env)); diff --git a/linux-user/main.c b/linux-user/main.c index 10a3bb3..79d621b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2590,17 +2590,17 @@ void cpu_loop(CPUOpenRISCState *env) case EXCP_SYSCALL: env->pc +=3D 4; /* 0xc00; */ ret =3D do_syscall(env, - env->gpr[11], /* return value */ - env->gpr[3], /* r3 - r7 are params */ - env->gpr[4], - env->gpr[5], - env->gpr[6], - env->gpr[7], - env->gpr[8], 0, 0); + cpu_get_gpr(env, 11), /* return value */ + cpu_get_gpr(env, 3), /* r3 - r7 are params */ + cpu_get_gpr(env, 4), + cpu_get_gpr(env, 5), + cpu_get_gpr(env, 6), + cpu_get_gpr(env, 7), + cpu_get_gpr(env, 8), 0, 0); if (ret =3D=3D -TARGET_ERESTARTSYS) { env->pc -=3D 4; } else if (ret !=3D -TARGET_QEMU_ESIGRETURN) { - env->gpr[11] =3D ret; + cpu_set_gpr(env, 11, ret); } break; case EXCP_DPF: @@ -4765,7 +4765,7 @@ int main(int argc, char **argv, char **envp) int i; =20 for (i =3D 0; i < 32; i++) { - env->gpr[i] =3D regs->gpr[i]; + cpu_set_gpr(env, i, regs->gpr[i]); } env->pc =3D regs->pc; cpu_set_sr(env, regs->sr); diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_= cpu.h index f283d96..606ad6f 100644 --- a/linux-user/openrisc/target_cpu.h +++ b/linux-user/openrisc/target_cpu.h @@ -23,14 +23,14 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong news= p) { if (newsp) { - env->gpr[1] =3D newsp; + cpu_set_gpr(env, 1, newsp); } - env->gpr[11] =3D 0; + cpu_set_gpr(env, 11, 0); } =20 static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls) { - env->gpr[10] =3D newtls; + cpu_set_gpr(env, 10, newtls); } =20 #endif diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/targ= et_signal.h index 9f2c493..95a733e 100644 --- a/linux-user/openrisc/target_signal.h +++ b/linux-user/openrisc/target_signal.h @@ -20,7 +20,7 @@ typedef struct target_sigaltstack { =20 static inline abi_ulong get_sp_from_cpustate(CPUOpenRISCState *state) { - return state->gpr[1]; + return cpu_get_gpr(state, 1); } =20 =20 diff --git a/linux-user/signal.c b/linux-user/signal.c index a67db04..eb6cb9f 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -4411,7 +4411,7 @@ static void setup_sigcontext(struct target_sigcontext= *sc, CPUOpenRISCState *regs, unsigned long mask) { - unsigned long usp =3D regs->gpr[1]; + unsigned long usp =3D cpu_get_gpr(regs, 1); =20 /* copy the regs. they are first in sc so we can use sc directly */ =20 @@ -4436,7 +4436,7 @@ static inline abi_ulong get_sigframe(struct target_si= gaction *ka, CPUOpenRISCState *regs, size_t frame_size) { - unsigned long sp =3D regs->gpr[1]; + unsigned long sp =3D cpu_get_gpr(regs, 1); int onsigstack =3D on_sig_stack(sp); =20 /* redzone */ @@ -4489,7 +4489,7 @@ static void setup_rt_frame(int sig, struct target_sig= action *ka, __put_user(0, &frame->uc.tuc_link); __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags); + __put_user(sas_ss_flags(cpu_get_gpr(env, 1)), &frame->uc.tuc_stack.ss_= flags); __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size); setup_sigcontext(&frame->sc, env, set->sig[0]); @@ -4512,13 +4512,13 @@ static void setup_rt_frame(int sig, struct target_s= igaction *ka, =20 /* Set up registers for signal handler */ env->pc =3D (unsigned long)ka->_sa_handler; /* what we enter NOW */ - env->gpr[9] =3D (unsigned long)return_ip; /* what we enter LATER */ - env->gpr[3] =3D (unsigned long)sig; /* arg 1: signo */ - env->gpr[4] =3D (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */ - env->gpr[5] =3D (unsigned long)&frame->uc; /* arg 3: ucontext */ + cpu_set_gpr(env, 9, (unsigned long)return_ip); /* what we enter LA= TER */ + cpu_set_gpr(env, 3, (unsigned long)sig); /* arg 1: signo */ + cpu_set_gpr(env, 4, (unsigned long)&frame->info); /* arg 2: (siginfo_= t*) */ + cpu_set_gpr(env, 5, (unsigned long)&frame->uc); /* arg 3: ucontext = */ =20 /* actually move the usp to reflect the stacked frame */ - env->gpr[1] =3D (unsigned long)frame; + cpu_set_gpr(env, 1, (unsigned long)frame); =20 return; =20 diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index 1524ed9..6c1ed07 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -52,7 +52,7 @@ static void openrisc_cpu_reset(CPUState *s) s->exception_index =3D -1; =20 cpu->env.upr =3D UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; - cpu->env.cpucfgr =3D CPUCFGR_OB32S | CPUCFGR_OF32S; + cpu->env.cpucfgr =3D CPUCFGR_OB32S | CPUCFGR_OF32S | CPUCFGR_NSGF; cpu->env.dmmucfgr =3D (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 <= < 2)); cpu->env.immucfgr =3D (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 <= < 2)); =20 @@ -132,6 +132,7 @@ static void or1200_initfn(Object *obj) { OpenRISCCPU *cpu =3D OPENRISC_CPU(obj); =20 + set_feature(cpu, OPENRISC_FEATURE_NSGF); set_feature(cpu, OPENRISC_FEATURE_OB32S); set_feature(cpu, OPENRISC_FEATURE_OF32S); set_feature(cpu, OPENRISC_FEATURE_EVBAR); @@ -141,6 +142,7 @@ static void openrisc_any_initfn(Object *obj) { OpenRISCCPU *cpu =3D OPENRISC_CPU(obj); =20 + set_feature(cpu, OPENRISC_FEATURE_NSGF); set_feature(cpu, OPENRISC_FEATURE_OB32S); set_feature(cpu, OPENRISC_FEATURE_EVBAR); } diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 1958b72..e159b22 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -275,7 +275,8 @@ typedef struct CPUOpenRISCTLBContext { #endif =20 typedef struct CPUOpenRISCState { - target_ulong gpr[32]; /* General registers */ + target_ulong shadow_gpr[16][32]; /* Shadow registers */ + target_ulong pc; /* Program counter */ target_ulong ppc; /* Prev PC */ target_ulong jmp_pc; /* Jump PC */ @@ -399,6 +400,16 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu, #define TB_FLAGS_R0_0 2 #define TB_FLAGS_OVE SR_OVE =20 +static inline uint32_t cpu_get_gpr(const CPUOpenRISCState *env, int i) +{ + return env->shadow_gpr[0][i]; +} + +static inline void cpu_set_gpr(CPUOpenRISCState *env, int i, uint32_t val) +{ + env->shadow_gpr[0][i] =3D val; +} + static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *f= lags) @@ -406,7 +417,7 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCStat= e *env, *pc =3D env->pc; *cs_base =3D 0; *flags =3D (env->dflag - | (env->gpr[0] =3D=3D 0 ? TB_FLAGS_R0_0 : 0) + | (cpu_get_gpr(env, 0) =3D=3D 0 ? TB_FLAGS_R0_0 : 0) | (env->sr & SR_OVE)); } =20 diff --git a/target/openrisc/gdbstub.c b/target/openrisc/gdbstub.c index b18c7e9..f9af650 100644 --- a/target/openrisc/gdbstub.c +++ b/target/openrisc/gdbstub.c @@ -28,7 +28,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t = *mem_buf, int n) CPUOpenRISCState *env =3D &cpu->env; =20 if (n < 32) { - return gdb_get_reg32(mem_buf, env->gpr[n]); + return gdb_get_reg32(mem_buf, cpu_get_gpr(env, n)); } else { switch (n) { case 32: /* PPC */ @@ -61,7 +61,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t= *mem_buf, int n) tmp =3D ldl_p(mem_buf); =20 if (n < 32) { - env->gpr[n] =3D tmp; + cpu_set_gpr(env, n, tmp); } else { switch (n) { case 32: /* PPC */ diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index 686eaa3..2bf71c3 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -47,10 +47,10 @@ static const VMStateInfo vmstate_sr =3D { =20 static const VMStateDescription vmstate_env =3D { .name =3D "env", - .version_id =3D 4, - .minimum_version_id =3D 4, + .version_id =3D 5, + .minimum_version_id =3D 5, .fields =3D (VMStateField[]) { - VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32), + VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32), VMSTATE_UINTTL(pc, CPUOpenRISCState), VMSTATE_UINTTL(ppc, CPUOpenRISCState), VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState), diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index e13666b..fa3d6a4 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -92,6 +92,11 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(0, 64): /* ESR */ env->esr =3D rb; break; + + case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */ + idx =3D (spr - 1024); + env->shadow_gpr[idx / 32][idx % 32] =3D rb; + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 = */ idx =3D spr - TO_SPR(1, 512); if (!(rb & 1)) { @@ -239,6 +244,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(0, 129): /* NUMCORES */ return 1; =20 + case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */ + idx =3D (spr - 1024); + return env->shadow_gpr[idx / 32][idx % 32]; + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 = */ idx =3D spr - TO_SPR(1, 512); return env->tlb->dtlb[0][idx].mr; diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index 7c4cbf2..e49518e 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -107,7 +107,8 @@ void openrisc_translate_init(void) "mac"); for (i =3D 0; i < 32; i++) { cpu_R[i] =3D tcg_global_mem_new(cpu_env, - offsetof(CPUOpenRISCState, gpr[i]), + offsetof(CPUOpenRISCState, + shadow_gpr[0][i]), regnames[i]); } cpu_R0 =3D cpu_R[0]; @@ -1662,7 +1663,7 @@ void openrisc_cpu_dump_state(CPUState *cs, FILE *f, =20 cpu_fprintf(f, "PC=3D%08x\n", env->pc); for (i =3D 0; i < 32; ++i) { - cpu_fprintf(f, "R%02d=3D%08x%c", i, env->gpr[i], + cpu_fprintf(f, "R%02d=3D%08x%c", i, cpu_get_gpr(env, i), (i % 4) =3D=3D 3 ? '\n' : ' '); } } --=20 2.9.3