Large RAM Powermac G5 powerpc64 openfirmware entry point use: I seem to have removed the major/frequent boot problem(s)

Mark Millard markmi at dsl-only.net
Sun Mar 1 08:49:46 UTC 2015


Having a working code combination and switching to finding the minimal change to FreeBSD's powerpc64 code that preserves the good behavior has shown that the required change to FreeBSD's powerpc64 code is tiny.

The code that must be changed for PowerMac G5 contexts is in ofw_sprg_prepare:

	__asm __volatile("mfsprg0 %0\n\t"
			 "mtsprg0 %1\n\t"
			 "mtsprg1 %2\n\t"
			 "mtsprg2 %3\n\t"
			 "mtsprg3 %4\n\t"
			 : "=&r"(ofw_sprg0_save)
			 : "r"(ofmsr[1]),
			 "r"(ofmsr[2]),
			 "r"(ofmsr[3]),
			 "r"(ofmsr[4]));

Specifically, the "mtsprg0 %1\n\t" must not be done: the FreeBSD SPRG0 value must be left in place before the use of ofwcall. The PowerMac G5 openfirmware treats SPRG0 as a scratch register initially (and later), not as having a value that must be preserved. SPRG0 from before FreeBSD has no stable initial value to put back here.

PowerMac G5 openfirmware entry point code does save SPRG0-SPRG3 but later depends on SPRG3's unchanged value to point to a pointer to use to store information. So "mtsprg3 %4\n\t" is required to be in place before the use of ofwcall: openfirmware requires the value, much like FreeBSD requires SPRG0 to be in place.

"mtsprg1 %2\n\t" and "mtsprg2 %3\n\t" are not needed but do not harm anything: Both FreeBSD and PowerMac G5 openfirmware treat them as scratch.

I've tested such changes with both 10.1-STABLE's ofwcall64.S and 11.0-CURRENT's ofwcall64.S (substituted into 10.1-STABLE and with sys/powerpc/include/asm.h from 11.0-CURRENT as well). Both ofwcall64.S's work when this change is in place. My initial, special ofwcall code that I was using is not needed.

[Again: I only claim that the most frequent boot failure disappears and that I've not found any .got corruptions when the change is in place. Other far less frequent boot failures that I've historically reported backtraces for may well still happen.]



I only have access to PowerMac G5 powerpc64 contexts (11,2 and 7,2, 8G RAM, 12G RAM and 16G RAM examples) so I can not claim any wider range of appropriateness than PowerMac G5s, not even other AIM contexts (if any).

So to not change the behavior for other contexts: I do not know if there is a reasonable "IsPowerMac" test but conceptually if an official change for the improvement was to be made it would need such a live check for a generic build that was to span PowerMac G5s and other things. I would not presume to remove "mtsprg0 %1\n\t" for other contexts.

My experimental code just plugs in a constant for where the live IsPowerMac test could possibly be:

#if defined(AIM) && defined(__powerpc64__)
/* HACK: PowerMac G5 specific code to avoid demonstrated hangs in
 *       the early boot time frame.
 *       This would need a live test for PowerMac vs. not in order
 *       to remove HACK status.
 */
        if (1)
                __asm __volatile("mfsprg0 %0\n\t"
                                 "mtsprg1 %1\n\t"
                                 "mtsprg2 %2\n\t"
                                 "mtsprg3 %3\n\t"
                                 : "=&r"(ofw_sprg0_save)
                                 : "r"(ofmsr[2]),
                                 "r"(ofmsr[3]),
                                 "r"(ofmsr[4]));
        else
#endif
        __asm __volatile("mfsprg0 %0\n\t"
                         "mtsprg0 %1\n\t"
                         "mtsprg1 %2\n\t"
                         "mtsprg2 %3\n\t"
                         "mtsprg3 %4\n\t"
                         : "=&r"(ofw_sprg0_save)
                         : "r"(ofmsr[1]),
                         "r"(ofmsr[2]),
                         "r"(ofmsr[3]),
                         "r"(ofmsr[4]));

But it also may be that there would be a desire to get the PowerMac specific code into sys/powerpc/powermac/... someplace.

I do hope that an official powerpc64 FreeBSD update for this can be made to help other PowerMac G5s boot more reliably.




Context details:

root at FBSDG5M1:/usr/src # freebsd-version -ku ; uname -a
10.1-STABLE
10.1-STABLE
FreeBSD FBSDG5M1 10.1-STABLE FreeBSD 10.1-STABLE #78 r279201M: Sat Feb 28 22:54:30 PST 2015     root at FBSDG5M1:/usr/obj/usr/src/sys/GENERIC64vtsc  powerpc

root at FBSDG5M1:/usr/src # svnlite info
Path: .
Working Copy Root Path: /usr/src
URL: https://svn0.us-west.freebsd.org/base/stable/10
Relative URL: ^/stable/10
Repository Root: https://svn0.us-west.freebsd.org/base
Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
Revision: 279201
Node Kind: directory
Schedule: normal
Last Changed Author: pluknet
Last Changed Rev: 279201
Last Changed Date: 2015-02-23 00:45:42 -0800 (Mon, 23 Feb 2015)

root at FBSDG5M1:/usr/src # svnlite st
?       .snap
M       sys/ddb/db_main.c
M       sys/ddb/db_script.c
 M      sys/powerpc/conf
?       sys/powerpc/conf/GENERIC64vtsc
M       sys/powerpc/ofw/ofw_machdep.c
M       sys/powerpc/ofw/ofwcall64.S

The ddb/...'s and ofw/ofwcall64.S are changed only to allow reporting information for  early failures as part of my investigation process (if any).

root at FBSDG5M1:/usr/src # more sys/powerpc/conf/GENERIC64vtsc 
include GENERIC64
ident   GENERIC64vtsc

nooptions       PS3                     #Sony Playstation 3               HACK!!! to allow sc

options         DDB                     # HACK!!! to dump early crash info (but 11.0-CURRENT already has it)
options         GDB                     # HACK!!! ...
#options        VERBOSE_SYSINIT
#options        BOOTVERBOSE=1
#options        BOOTHOWTO=RB_VERBOSE
#options        KTR
#options        KTR_MASK=KTR_TRAP
#options        KTR_CPUMASK=0xF
#options        KTR_VERBOSE

# HACK!!! to allow sc for 2560x1440 display on Radeon X1950 that vt historically mishandled during booting
device          sc
#device          kbdmux         # HACK: already listed by vt
options         SC_OFWFB        # OFW frame buffer
options         SC_DFLT_FONT    # compile font in
makeoptions     SC_DFLT_FONT=cp437


# Disable extra checking typically used for FreeBSD 11.0-CURRENT:
nooptions       DEADLKRES               #Enable the deadlock resolver
nooptions       INVARIANTS              #Enable calls of extra sanity checking
nooptions       INVARIANT_SUPPORT       #Extra sanity checks of internal structures, required by INVARIANTS
nooptions       WITNESS                 #Enable checks to detect deadlocks and cycles
nooptions       WITNESS_SKIPSPIN        #Don't run witness on spinlocks for speed
nooptions       MALLOC_DEBUG_MAXZONES   # Separate malloc(9) zones

root at FBSDG5M1:/usr/src # more /etc/make.conf
WRKDIRPREFIX=/usr/obj/portswork
WITH_DEBUG=
MALLOC_PRODUCTION=

root at FBSDG5M1:/usr/src # more /etc/src.conf
#CFLAGS+=-DELF_VERBOSE
#WITH_DEBUG_FILES=
#WITHOUT_CLANG=

===
Mark Millard
markmi at dsl-only.net




More information about the freebsd-ppc mailing list