8.17.2008

odd discovery

I was fighting with the OF_peer() to check if it passes the openfirmware() call, which is OF entry and after lots of tries it seems that it does. It's very different from what I thought before. After using ofw_stack() from NetBSD in OF_peer() as it was done in OF_read()/OF_write(), that function seems to be working but the crash remains. 

Here's the dump:

DEBUG 2
done.
subsystem 2100000
  freebsd4_sigreturn(0)...
cpu_startup() DEBUG 0
** DEBUGL OF_printf(): after OF_peer() in decr_init()
cpu_exception:
SRR0 0x004A0DF0 SRR1 0x00003030 MSR 0x00003030
LR 0x01003ED8 CTR 0x00000000 CR 0x24002044 XER 0x0
DAR 0xD0004D3C DSISR 0x42000000 Type 3
========================
What is very strange, during the trace I've encountered the call to OF_write() just after OF_peer(), like there were _two_ calls to openfirmware() insted of one. And it's the second one that crashes... Now, what I don't get is where from this second call come ? There's no printf() around OF_peer()...:

========================

from: sys/dev/ofw/openfirm.c

phandle_t
OF_peer(phandle_t node)
{
      static struct {
      cell_t name;
      cell_t nargs;
      cell_t nreturns;
      cell_t node;
      cell_t next; }

               args = {
                           (cell_t)"peer",
                            1,
                            1,
                            };


  ofw_stack();
  args.node = node;
  if (openfirmware(&args) == -1)
  return (-1);
  return (args.next);
}
=========================

6 comments:

Andrew said...

Have you checked OF_peer is returning and the crash is happening in another of the OF_ functions?

vi0 said...

OF_peer() is returning, and it enters OF_getprop() after that. Then it crashes, even with the code from NetBSD.

Andrew said...

That is likely because args.buf points to a virtual address.

You could try and use OF_buf rather than buf then copy the result from OF_buf to buf after openfirmware returns. For an example of this look at OF_read.

args.propname should not need to be copied to OF_buf as it is (as far as I can tell) always a const char * and so it's address is valid.

While there you will also need to add ofw_stack to OF_child and OF_parent as they are used later on in decr_init.

vi0 said...

I did so, at the beginning I've added the OF_buf and copied it afterwards. But then, it crashes immediately, it doesn't even make it to single character of copyrights... I added OF_buf to most of the OF functions, to each one that in NetBSD's openfirm.c has it. If I don't use OF_buf in OF_getprop(), and comment out the decr_init(), it makes it do subsystem 38000000, just like I wrote on the blog... At the moment, apart from that, I'm stuck on the mtspr sprg0, that hangs in openfirmware(), in OF_getprop()...

Andrew said...

That is likely because OF_getprop is called early on in the process before OF_buf has been allocated. At this point in the boot process it is safe to call out to openfirmware without using OF_buf.

I'd put a check in if OF_buff is not null use it otherwise use buf. After the call to openfirmware if OF_buf is not NULL copy it's contents to buf.

vi0 said...

Yaeah! That worked! I'll make a blog entry... Thanks!