Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/oea introduce a inline function to set a va...



details:   https://anonhg.NetBSD.org/src/rev/ad97bf49019a
branches:  trunk
changeset: 829753:ad97bf49019a
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sun Feb 11 00:01:12 2018 +0000

description:
introduce a inline function to set a value to zero while
hiding this fact from GCC.  this allows the PPC code that
writes to address zero to actually work rather than cause
GCC to emit an explicit "trap" instruction, which in early
boot means hang on my pegasosII.  use this in oae_init()
for both rfid->rfi and also setting the jump-to-zero trap.

found with a lot of debugging, but GCC 6's new warning
-Wnull-dereference found it when i was informed of its
existence.  unfortunately, there are dozens of other
violations in our kernel today so simply enabling that
option for everything is not a good idea, but is a goal.

diffstat:

 sys/arch/powerpc/oea/oea_machdep.c |  25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diffs (60 lines):

diff -r 8e0a5eaab843 -r ad97bf49019a sys/arch/powerpc/oea/oea_machdep.c
--- a/sys/arch/powerpc/oea/oea_machdep.c        Sat Feb 10 23:46:44 2018 +0000
+++ b/sys/arch/powerpc/oea/oea_machdep.c        Sun Feb 11 00:01:12 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: oea_machdep.c,v 1.73 2016/05/30 13:04:24 chs Exp $     */
+/*     $NetBSD: oea_machdep.c,v 1.74 2018/02/11 00:01:12 mrg Exp $     */
 
 /*
  * Copyright (C) 2002 Matt Thomas
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.73 2016/05/30 13:04:24 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.74 2018/02/11 00:01:12 mrg Exp $");
 
 #include "opt_ppcarch.h"
 #include "opt_compat_netbsd.h"
@@ -109,6 +109,19 @@
 extern int dsitrap_fix_dbat6[];
 extern int dsitrap_fix_dbat7[];
 
+/*
+ * Load pointer with 0 behind GCC's back, otherwise it will
+ * emit a "trap" instead.
+ */
+static __inline__ uintptr_t
+zero_value(void)
+{
+       uintptr_t dont_tell_gcc;
+
+       __asm volatile ("li %0, 0" : "=r"(dont_tell_gcc) :);
+       return dont_tell_gcc;
+}
+
 void
 oea_init(void (*handler)(void))
 {
@@ -144,7 +157,7 @@
 #ifdef PPC_HIGH_VEC
        exc_base = EXC_HIGHVEC;
 #else
-       exc_base = 0;
+       exc_base = zero_value();
 #endif
        KASSERT(mfspr(SPR_SPRG0) == (uintptr_t)ci);
 
@@ -289,8 +302,10 @@
         * Install a branch absolute to trap0 to force a panic.
         */
        if ((uintptr_t)trap0 < 0x2000000) {
-               *(volatile uint32_t *) 0 = 0x7c6802a6;
-               *(volatile uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
+               uint32_t *p = (uint32_t *)zero_value();
+
+               p[0] = 0x7c6802a6;
+               p[1] = 0x48000002 | (uintptr_t) trap0;
        }
 
        /*



Home | Main Index | Thread Index | Old Index