From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NVtov-0003pI-M4 for qemu-devel@nongnu.org; Fri, 15 Jan 2010 16:35:05 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NVtor-0003nW-SQ for qemu-devel@nongnu.org; Fri, 15 Jan 2010 16:35:05 -0500 Received: from [199.232.76.173] (port=44370 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NVtor-0003nQ-OQ for qemu-devel@nongnu.org; Fri, 15 Jan 2010 16:35:01 -0500 Received: from mail-pz0-f190.google.com ([209.85.222.190]:55077) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NVtor-0003hY-9w for qemu-devel@nongnu.org; Fri, 15 Jan 2010 16:35:01 -0500 Received: by pzk28 with SMTP id 28so340453pzk.4 for ; Fri, 15 Jan 2010 13:35:00 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <1263590936-17505-1-git-send-email-atar4qemu@google.com> References: <1263590936-17505-1-git-send-email-atar4qemu@google.com> From: Blue Swirl Date: Fri, 15 Jan 2010 21:34:40 +0000 Message-ID: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] Re: sparc32 do_unassigned_access overhaul v2 List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Artyom Tarasenko Cc: qemu-devel@nongnu.org, Artyom Tarasenko Thanks, applied. On Fri, Jan 15, 2010 at 9:28 PM, Artyom Tarasenko wrote: > According to pages 9-31 - 9-34 of "SuperSPARC & MultiCache Controller > User's Manual": > > 1. "A lower priority fault may not overwrite the > =C2=A0 =C2=A0MFSR status of a higher priority fault." > 2. The MFAR is overwritten according to the policy defined for the MFSR > 3. The overwrite bit is asserted if the fault status register (MFSR) > =C2=A0 has been written more than once by faults of the same class > 4. SuperSPARC will never place instruction fault addresses in the MFAR. > > Implementation of points 1-3 allows booting Solaris 2.6 and 2.5.1. > > v2: CODING_STYLE fixes > > Signed-off-by: Artyom Tarasenko > --- > diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c > index 381e6c4..3ff35d3 100644 > --- a/target-sparc/op_helper.c > +++ b/target-sparc/op_helper.c > @@ -3714,6 +3714,7 @@ void do_unassigned_access(target_phys_addr_t addr, = int is_write, int is_exec, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 int is_asi, int size) > =C2=A0{ > =C2=A0 =C2=A0 CPUState *saved_env; > + =C2=A0 =C2=A0int fault_type; > > =C2=A0 =C2=A0 /* XXX: hack to restore env in all cases, even if not calle= d from > =C2=A0 =C2=A0 =C2=A0 =C2=A0generated code */ > @@ -3731,18 +3732,29 @@ void do_unassigned_access(target_phys_addr_t addr= , int is_write, int is_exec, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0is_exec ? "exec" := is_write ? "write" : "read", size, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0size =3D=3D 1 ? ""= : "s", addr, env->pc); > =C2=A0#endif > - =C2=A0 =C2=A0if (env->mmuregs[3]) /* Fault status register */ > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] =3D 1; /* overflow (not read= before another fault) */ > - =C2=A0 =C2=A0if (is_asi) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 16; > - =C2=A0 =C2=A0if (env->psrs) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 5; > - =C2=A0 =C2=A0if (is_exec) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 6; > - =C2=A0 =C2=A0if (is_write) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 7; > - =C2=A0 =C2=A0env->mmuregs[3] |=3D (5 << 2) | 2; > - =C2=A0 =C2=A0env->mmuregs[4] =3D addr; /* Fault address register */ > + =C2=A0 =C2=A0/* Don't overwrite translation and access faults */ > + =C2=A0 =C2=A0fault_type =3D (env->mmuregs[3] & 0x1c) >> 2; > + =C2=A0 =C2=A0if ((fault_type > 4) || (fault_type =3D=3D 0)) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] =3D 0; /* Fault status regis= ter */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (is_asi) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 16; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (env->psrs) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 5; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (is_exec) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 6; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (is_write) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1 << 7; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D (5 << 2) | 2; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SuperSPARC will never place instruction f= ault addresses in the FAR */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!is_exec) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[4] =3D addr; /* F= ault address register */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0/* overflow (same type fault was not read before another f= ault) */ > + =C2=A0 =C2=A0if (fault_type =3D=3D ((env->mmuregs[3] & 0x1c)) >> 2) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->mmuregs[3] |=3D 1; > + =C2=A0 =C2=A0} > + > =C2=A0 =C2=A0 if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF= )) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (is_exec) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise_exception(TT_CODE_ACCESS)= ; > @@ -3750,6 +3762,12 @@ void do_unassigned_access(target_phys_addr_t addr,= int is_write, int is_exec, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise_exception(TT_DATA_ACCESS)= ; > =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 env =3D saved_env; > + > + =C2=A0 =C2=A0/* flush neverland mappings created during no-fault mode, > + =C2=A0 =C2=A0 =C2=A0 so the sequential MMU faults report proper fault t= ypes */ > + =C2=A0 =C2=A0if (env->mmuregs[0] & MMU_NF) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0tlb_flush(env, 1); > + =C2=A0 =C2=A0} > =C2=A0} > =C2=A0#else > =C2=A0void do_unassigned_access(target_phys_addr_t addr, int is_write, in= t is_exec, >