Fri Jan 7 15:14:24 2011 UTC ()
Add support for emulating mfpvr and lwsync.  GCC will emit lwsync but booke
doesn't lwsync (sync 1) so we "emulate" it by treating it as a noop since
the exception will have synchronized things for us.


(matt)
diff -r1.1.2.1 -r1.1.2.2 src/sys/arch/powerpc/booke/trap.c

cvs diff -r1.1.2.1 -r1.1.2.2 src/sys/arch/powerpc/booke/trap.c (expand / switch to unified diff)

--- src/sys/arch/powerpc/booke/trap.c 2011/01/07 01:26:19 1.1.2.1
+++ src/sys/arch/powerpc/booke/trap.c 2011/01/07 15:14:23 1.1.2.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: trap.c,v 1.1.2.1 2011/01/07 01:26:19 matt Exp $ */ 1/* $NetBSD: trap.c,v 1.1.2.2 2011/01/07 15:14:23 matt Exp $ */
2/*- 2/*-
3 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. 3 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects 7 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
8 * Agency and which was developed by Matt Thomas of 3am Software Foundry. 8 * Agency and which was developed by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * This material is based upon work supported by the Defense Advanced Research 10 * This material is based upon work supported by the Defense Advanced Research
11 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under 11 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
12 * Contract No. N66001-09-C-2073. 12 * Contract No. N66001-09-C-2073.
13 * Approved for Public Release, Distribution Unlimited 13 * Approved for Public Release, Distribution Unlimited
14 * 14 *
@@ -29,46 +29,48 @@ @@ -29,46 +29,48 @@
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include "opt_ddb.h" 37#include "opt_ddb.h"
38#include "opt_sa.h" 38#include "opt_sa.h"
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41 41
42__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.1.2.1 2011/01/07 01:26:19 matt Exp $"); 42__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.1.2.2 2011/01/07 15:14:23 matt Exp $");
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/siginfo.h> 46#include <sys/siginfo.h>
47#include <sys/user.h> 47#include <sys/user.h>
48#include <sys/lwp.h> 48#include <sys/lwp.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/cpu.h> 50#include <sys/cpu.h>
51#ifdef KERN_SA 51#ifdef KERN_SA
52#include <sys/savar.h> 52#include <sys/savar.h>
53#endif 53#endif
54#include <sys/kauth.h> 54#include <sys/kauth.h>
55#include <sys/kmem.h> 55#include <sys/kmem.h>
 56#include <sys/ras.h>
56 57
57#include <uvm/uvm_extern.h> 58#include <uvm/uvm_extern.h>
58 59
59#include <powerpc/pcb.h> 60#include <powerpc/pcb.h>
60#include <powerpc/userret.h> 61#include <powerpc/userret.h>
61#include <powerpc/psl.h> 62#include <powerpc/psl.h>
 63#include <powerpc/instr.h>
62 64
63#include <powerpc/spr.h> 65#include <powerpc/spr.h>
64#include <powerpc/booke/spr.h> 66#include <powerpc/booke/spr.h>
65 67
66#include <powerpc/db_machdep.h> 68#include <powerpc/db_machdep.h>
67#include <ddb/db_interface.h> 69#include <ddb/db_interface.h>
68 70
69#include <powerpc/trap.h> 71#include <powerpc/trap.h>
70#include <powerpc/booke/trap.h> 72#include <powerpc/booke/trap.h>
71#include <powerpc/booke/pte.h> 73#include <powerpc/booke/pte.h>
72 74
73void trap(enum ppc_booke_exceptions, struct trapframe *); 75void trap(enum ppc_booke_exceptions, struct trapframe *);
74static void dump_trapframe(const struct trapframe *); 76static void dump_trapframe(const struct trapframe *);
@@ -375,48 +377,84 @@ itlb_exception(struct trapframe *tf, ksi @@ -375,48 +377,84 @@ itlb_exception(struct trapframe *tf, ksi
375 usertrap); 377 usertrap);
376 378
377 if (__predict_false(rv != 0 && usertrap)) { 379 if (__predict_false(rv != 0 && usertrap)) {
378 ci->ci_ev_isi_fatal.ev_count++; 380 ci->ci_ev_isi_fatal.ev_count++;
379 KSI_INIT_TRAP(ksi); 381 KSI_INIT_TRAP(ksi);
380 ksi->ksi_signo = SIGSEGV; 382 ksi->ksi_signo = SIGSEGV;
381 ksi->ksi_trap = EXC_ISI; 383 ksi->ksi_trap = EXC_ISI;
382 ksi->ksi_code = (rv == EACCES ? SEGV_ACCERR : SEGV_MAPERR); 384 ksi->ksi_code = (rv == EACCES ? SEGV_ACCERR : SEGV_MAPERR);
383 ksi->ksi_addr = (void *)tf->tf_srr0; 385 ksi->ksi_addr = (void *)tf->tf_srr0;
384 } 386 }
385 return rv; 387 return rv;
386} 388}
387 389
 390static bool
 391emulate_opcode(struct trapframe *tf, ksiginfo_t *ksi)
 392{
 393 uint32_t opcode;
 394 if (copyin((void *)tf->tf_srr0, &opcode, sizeof(opcode)) != 0)
 395 return false;
 396
 397 if (opcode == OPC_LWSYNC)
 398 return true;
 399
 400 if (OPC_MFSPR_P(opcode, SPR_PVR)) {
 401 __asm ("mfpvr %0" : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)]));
 402 return true;
 403 }
 404
 405 /*
 406 * If we bothered to emulate FP, we would try to do so here.
 407 */
 408 return false;
 409}
388 410
389static int 411static int
390pgm_exception(struct trapframe *tf, ksiginfo_t *ksi) 412pgm_exception(struct trapframe *tf, ksiginfo_t *ksi)
391{ 413{
392 struct cpu_info * const ci = curcpu(); 414 struct cpu_info * const ci = curcpu();
393 int rv = EPERM; 415 int rv = EPERM;
394 416
395 if (rv != 0 && usertrap_p(tf)) { 417 if (!usertrap_p(tf))
396 ci->ci_ev_pgm.ev_count++; 418 return rv;
397 KSI_INIT_TRAP(ksi); 419
398 ksi->ksi_signo = SIGILL; 420 ci->ci_ev_pgm.ev_count++;
399 ksi->ksi_trap = EXC_PGM; 421
400 if (tf->tf_esr & ESR_PIL) 422 if (tf->tf_esr & ESR_PTR) {
401 ksi->ksi_code = ILL_ILLOPC; 423 struct proc *p = curlwp->l_proc;
402 else if (tf->tf_esr & ESR_PPR) 424 if (p->p_raslist != NULL
403 ksi->ksi_code = ILL_PRVOPC; 425 && ras_lookup(p, (void *)tf->tf_srr0) != (void *) -1) {
404 else if (tf->tf_esr & ESR_PTR) 426 tf->tf_srr0 += 4;
405 ksi->ksi_code = ILL_ILLTRP; 427 return 0;
406 else 428 }
407 ksi->ksi_code = 0; 429 } else if (tf->tf_esr & (ESR_PIL|ESR_PPR)) {
408 ksi->ksi_addr = (void *)tf->tf_srr0; 430 if (emulate_opcode(tf, ksi)) {
 431 tf->tf_srr0 += 4;
 432 return 0;
 433 }
409 } 434 }
 435
 436 KSI_INIT_TRAP(ksi);
 437 ksi->ksi_signo = SIGILL;
 438 ksi->ksi_trap = EXC_PGM;
 439 if (tf->tf_esr & ESR_PIL)
 440 ksi->ksi_code = ILL_ILLOPC;
 441 else if (tf->tf_esr & ESR_PPR)
 442 ksi->ksi_code = ILL_PRVOPC;
 443 else if (tf->tf_esr & ESR_PTR)
 444 ksi->ksi_code = ILL_ILLTRP;
 445 else
 446 ksi->ksi_code = 0;
 447 ksi->ksi_addr = (void *)tf->tf_srr0;
410 return rv; 448 return rv;
411} 449}
412 450
413static int 451static int
414ali_exception(struct trapframe *tf, ksiginfo_t *ksi) 452ali_exception(struct trapframe *tf, ksiginfo_t *ksi)
415{ 453{
416 struct cpu_info * const ci = curcpu(); 454 struct cpu_info * const ci = curcpu();
417 int rv = EFAULT; 455 int rv = EFAULT;
418 456
419 ci->ci_ev_ali.ev_count++; 457 ci->ci_ev_ali.ev_count++;
420 458
421 if (rv != 0 && usertrap_p(tf)) { 459 if (rv != 0 && usertrap_p(tf)) {
422 ci->ci_ev_ali_fatal.ev_count++; 460 ci->ci_ev_ali_fatal.ev_count++;