Re: 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 via freebsd-ppc <[email protected]>
Newsgroups gmane.os.freebsd.devel.ppc
Message-ID <[email protected]>
[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@f2000000//mac-io@17/gpio@50/gpio5@6f (gpio5@6f), skipping
Error -2 adding node /pci@f2000000//mac-io@17/gpio@50/gpio6@70 (gpio6@70), skipping
Error -2 adding node /pci@f2000000//mac-io@17/gpio@50/gpio11@75 (gpio11@75), skipping
Error -2 adding node /pci@f2000000//mac-io@17/extint-gpio@15@67 (extint-gpio@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)

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-ppc
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.