head -r345758: usefdt=1 style boot fails on PowerMac7,2 G5 (1 core per socket): Error -2 adding node /cpus/PowerpC,970 [G4 failures too, problem identified]

Mark Millard marklmi at yahoo.com
Sun Apr 7 21:36:43 UTC 2019


[The problem also exists on 32-bit powerpc, at least for
a PowerMac3,6 example. In this context I was able to gather
evidence for the problem, unlike for the PowerMac7,2 .]

On 2019-Apr-7, at 05:14, Mark Millard <marklmi at yahoo.com> wrote:

> [The same SSDs boot the 2 PowerMac11,2 G5 (2-socket/2-core-per-socket)
> just fine. I temporarily have access to the PowerMac7,2 and a
> different 11,2 G5 that has only 12 GiBytes of RAM --but not the
> 16 GiByte one. ]
> 
> Both powerpc64 FreeBSD (built via system-clang) and 32-bit powerpc
> FreeBSD (built via gcc 4.2.1) fail the same way.
> 
> The failure looks like (from a picture of a powerpc64
> attempt):
> 
> Booting [/boot/kernel/kernel]. . .
> Error -2 adding node /cpus/PowerPC,970 (PowerPC,970), skipping
> Kernel entry at 0x100100 . . .
> 
> (and that is the end of the output).
> 
> Note: I had modified the kernel to not require an explicit usefdt=1
> --in fact giving not control in the other direction either. So,
> always using usefdt=1 mode. I had intended to stick with testing
> usefdt=1 mode.
> 
> Result: As stands I do not have media set up that can boot the
> 7,2 . This means that I've not checked any contrasting cases
> that do not involve usefdt=1 style behavior.
> 
> Thus my attribution of the problem to usefdt=1 style behavior is
> not validated.

I have temporary access to some old PowerMac G4s. So I tried
booting a PowerMac3,6 1.42 GHz Dual Processor FW800 as an initial
experiment. This note reports the failed results

While it does not stop booting . . .

It boots as a single CPU machine with no ethernet device (for
an example of something else that is missing).

It does briefly show messages like:

Error -2 adding node /cpus/PowerPC,G4 (PowerPC,G4), skipping
Error -2 adding node /pci at f2000000//mac-io at 17/gpio at 50/gpio5 at 6f (gpio5 at 6f), skipping
Error -2 adding node /pci at f2000000//mac-io at 17/gpio at 50/gpio6 at 70 (gpio6 at 70), skipping
Error -2 adding node /pci at f2000000//mac-io at 17/gpio at 50/gpio11 at 75 (gpio11 at 75), skipping
Error -2 adding node /pci at f2000000//mac-io at 17/extint-gpio at 15@67 (extint-gpio at 15@67), skipping

It appears that -2 is: -FDT_ERR_EXISTS

#define FDT_ERR_EXISTS          2
        /* FDT_ERR_EXISTS: Attempted to create a node or property which
         * already exists */

The below shows my evidence that for the PowerMac3,6 in
question "/cpus/PowerPC,G4" is apparently not a unique
textual identification --and that needs to be handled but
is not. (The PowerMac7,2 may be similar but did not boot
to where I could easily explore.) [I've not gone through
the details for the gpio "skipping" reports.]

[On the PowerMac3.6 I did: ofwdump -ap > /root/ofwdump_bad.txt
Later I looked at the drive in another machine.]

ofwdump -ap reports for cpus on the PowerMac3,6:

# grep -i cpus /mnt/root/ofwdump_bad.txt 
  Node 0x73d0: cpus
    #cpus:
      'cpus'

(later this will be contrasted with the PowerMac11,2 context).

Looking:

  Node 0x73d0: cpus
    phandle:
      ff 88 34 00 
      '\M^?\M^H4'
    core-temp:
      00 00 00 41 
    core-voltage:
      00 00 00 9b 
    #cpus:
      00 00 00 02 
    #size-cells:
      00 00 00 00 
    #address-cells:
      00 00 00 01 
    name:
      63 70 75 73 00 
      'cpus'
    Node 0x7450: PowerPC,G4
      phandle:
        ff 88 36 d8 
      gpio-parent:
        ff 96 41 d0 
. . .

But:

# grep -i powerpc /mnt/root/ofwdump_bad.txt
        driver,AAPL,MacOS,PowerPC:
    Node 0x7450: PowerPC,G4

(There is only the one PowerPC,G4 Node present in the dump
output --because the 2nd was treated as in error at boot.)

My interpretation is that there are 2:

/cpus/PowerPC,G4
/cpus/PowerPC,G4

with no textual differentiation. The Node 0x???? figures
seem to be the differentiation.

This looks different than on the PowerMac11,2 :

# ofwdump -ap | grep -i cpus
      '/cpus/@3'
      '/cpus/@2'
      '/cpus/@1'
      '/cpus/@0'
  Node 0xc7f4: cpus
      'cpus'

# ofwdump -ap | grep -i powerpc
    Node 0xc864: PowerPC,G5
        'PowerPC,G5'
    Node 0xcb4c: PowerPC,G5
        'PowerPC,G5'
    Node 0xce34: PowerPC,G5
        'PowerPC,G5'
    Node 0xd11c: PowerPC,G5
        'PowerPC,G5'

In this context /cpus/@N/PowerMacPC,G5 is unique textually
without needing the 0x???? figures for the Node's.


This matches up with what I see in the code: it is
checking for a textual differentiation and only the
PowerMac11,2 appears to have such (of what I've
seen). The details of tracing the code down follow.

The code that reports the failures is:

static void
add_node_to_fdt(void *buffer, phandle_t node, int fdt_offset)
{
        int i, child_offset, error;
        char name[255], *lastprop, *subname;
        void *propbuf;
        ssize_t proplen;
. . .
        for (node = OF_child(node); node > 0; node = OF_peer(node)) {
                OF_package_to_path(node, name, sizeof(name));
                subname = strrchr(name, '/');
                subname++;
                child_offset = fdt_add_subnode(buffer, fdt_offset, subname);
                if (child_offset < 0) {
                        printf("Error %d adding node %s (%s), skipping\n",
                            child_offset, name, subname);
                        continue;
                }

                add_node_to_fdt(buffer, node, child_offset);
        }
}

where:

int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
{
        return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
}

and:

int fdt_add_subnode_namelen(void *fdt, int parentoffset,
                            const char *name, int namelen)
{
        struct fdt_node_header *nh;
        int offset, nextoffset;
        int nodelen;
        int err;
        uint32_t tag;
        fdt32_t *endtag;

        FDT_RW_CHECK_HEADER(fdt);

        offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
        if (offset >= 0)
                return -FDT_ERR_EXISTS;
. . .

and:

int fdt_subnode_offset_namelen(const void *fdt, int offset,
                               const char *name, int namelen)
{
        int depth;

        FDT_CHECK_HEADER(fdt);

        for (depth = 0;
             (offset >= 0) && (depth >= 0);
             offset = fdt_next_node(fdt, offset, &depth))
                if ((depth == 1)
                    && fdt_nodename_eq_(fdt, offset, name, namelen))
                        return offset;
 
        if (depth < 0)
                return -FDT_ERR_NOTFOUND;
        return offset; /* error */
}

where:

static int fdt_nodename_eq_(const void *fdt, int offset,
                            const char *s, int len)
{
        int olen;
        const char *p = fdt_get_name(fdt, offset, &olen);
        
        if (!p || olen < len)
                /* short match */
                return 0;
             
        if (memcmp(p, s, len) != 0)
                return 0;
                        
        if (p[len] == '\0')
                return 1;
        else if (!memchr(s, '@', len) && (p[len] == '@'))
                return 1;
        else
                return 0;
}

No consideration of distinct 0x???? figures for
Node are made by fdt_subnode_offset_namelen .
At least for the PowerMac3,6 such a differentiation
is required if usefdt=1 style is to work.


===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)



More information about the freebsd-ppc mailing list