Breakpoint 4, obp_devread (dev_desc=-2400864, buf=0xf00a30ec "\240", nbytes=8192) at ../arch/sparc32/romvec.c:314 314 PUSH((int)buf); (gdb) next 315 PUSH(nbytes); (gdb) next 316 push_str("read"); (gdb) next 317 PUSH(dev_desc); (gdb) next 318 fword("$call-method"); // just in case (gdb) info registers g0 0x0 0 g1 0x4c 76 g2 0xffd4f1b0 -2821712 g3 0x13 19 g4 0xffdb5da0 -2400864 g5 0x0 0 g6 0x0 0 g7 0x0 0 o0 0xffdb5da0 -2400864 o1 0x0 0 o2 0xf00a30ec -267767572 o3 0x20 32 o4 0x10 16 o5 0x0 0 sp 0x125fb0 0x125fb0 o7 0xffd05eb0 -3121488 l0 0x4401dc4 71310788 l1 0x10e6dc 1107676 l2 0x107388 1078152 l3 0x40 64 l4 0x80 128 l5 0x0 0 l6 0x0 0 l7 0x0 0 i0 0xffdb5da0 -2400864 i1 0xf00a30ec -267767572 i2 0x2000 8192 i3 0xfffffffc -4 i4 0x20 32 i5 0x10f444 1111108 fp 0x126020 0x126020 i7 0x10e88c 1108108 y 0x800 2048 psr 0x4401de4 [ #2 ET PS S #8 #10 #11 EF #22 #26 ] wim 0x40 64 tbr 0xffd00060 -3145632 pc 0xffd05eb8 0xffd05eb8 <obp_devread+80> npc 0xffd05ebc 0xffd05ebc <obp_devread+84> fsr 0x80000 [ #19 ] csr 0x0 0
// here resides Solaris's printf:
(gdb) disas 0x00104798, 0x001047c0 Dump of assembler code from 0x104798 to 0x1047c0: 0x00104798: save %sp, -96, %sp 0x0010479c: st %i1, [ %fp + 0x48 ] 0x001047a0: mov %i0, %o0 0x001047a4: st %i2, [ %fp + 0x4c ] 0x001047a8: add %fp, 0x48, %o1 0x001047ac: st %i3, [ %fp + 0x50 ] 0x001047b0: st %i4, [ %fp + 0x54 ] 0x001047b4: call 0x10f4a8 0x001047b8: st %i5, [ %fp + 0x58 ] 0x001047bc: ret End of assembler dump. (gdb) next 319 ret = POP();
// Oooops, not anymore
(gdb) disas 0x00104798, 0x001047c0 Dump of assembler code from 0x104798 to 0x1047c0: 0x00104798: bne,a 0x1046bc 0x0010479c: ld [ %i0 + 0x14 ], %o0 0x001047a0: ld [ %i1 + 0x10 ], %i4 0x001047a4: cmp %i4, %i2 0x001047a8: be 0x104894 0x001047ac: nop 0x001047b0: ld [ %i4 + 0x10 ], %o0 0x001047b4: call 0x1048fc 0x001047b8: nop 0x001047bc: mov %o0, %i1 End of assembler dump.
reading 8192 bytes into the address 0xf00a30ec corrupts 0x00104798.
Is there an easy way to see from gdb where the both addresses are mapped to? "map?" seems to be not implemented in the OpenBIOS.
Artyom Tarasenko wrote:
Breakpoint 4, obp_devread (dev_desc=-2400864, buf=0xf00a30ec "\240", nbytes=8192) at ../arch/sparc32/romvec.c:314 314 PUSH((int)buf); (gdb) next 315 PUSH(nbytes); (gdb) next 316 push_str("read"); (gdb) next 317 PUSH(dev_desc); (gdb) next 318 fword("$call-method"); // just in case (gdb) info registers g0 0x0 0 g1 0x4c 76 g2 0xffd4f1b0 -2821712 g3 0x13 19 g4 0xffdb5da0 -2400864 g5 0x0 0 g6 0x0 0 g7 0x0 0 o0 0xffdb5da0 -2400864 o1 0x0 0 o2 0xf00a30ec -267767572 o3 0x20 32 o4 0x10 16 o5 0x0 0 sp 0x125fb0 0x125fb0 o7 0xffd05eb0 -3121488 l0 0x4401dc4 71310788 l1 0x10e6dc 1107676 l2 0x107388 1078152 l3 0x40 64 l4 0x80 128 l5 0x0 0 l6 0x0 0 l7 0x0 0 i0 0xffdb5da0 -2400864 i1 0xf00a30ec -267767572 i2 0x2000 8192 i3 0xfffffffc -4 i4 0x20 32 i5 0x10f444 1111108 fp 0x126020 0x126020 i7 0x10e88c 1108108 y 0x800 2048 psr 0x4401de4 [ #2 ET PS S #8 #10 #11 EF #22 #26 ] wim 0x40 64 tbr 0xffd00060 -3145632 pc 0xffd05eb8 0xffd05eb8 <obp_devread+80> npc 0xffd05ebc 0xffd05ebc <obp_devread+84> fsr 0x80000 [ #19 ] csr 0x0 0
// here resides Solaris's printf:
(gdb) disas 0x00104798, 0x001047c0 Dump of assembler code from 0x104798 to 0x1047c0: 0x00104798: save %sp, -96, %sp 0x0010479c: st %i1, [ %fp + 0x48 ] 0x001047a0: mov %i0, %o0 0x001047a4: st %i2, [ %fp + 0x4c ] 0x001047a8: add %fp, 0x48, %o1 0x001047ac: st %i3, [ %fp + 0x50 ] 0x001047b0: st %i4, [ %fp + 0x54 ] 0x001047b4: call 0x10f4a8 0x001047b8: st %i5, [ %fp + 0x58 ] 0x001047bc: ret End of assembler dump. (gdb) next 319 ret = POP();
// Oooops, not anymore
(gdb) disas 0x00104798, 0x001047c0 Dump of assembler code from 0x104798 to 0x1047c0: 0x00104798: bne,a 0x1046bc 0x0010479c: ld [ %i0 + 0x14 ], %o0 0x001047a0: ld [ %i1 + 0x10 ], %i4 0x001047a4: cmp %i4, %i2 0x001047a8: be 0x104894 0x001047ac: nop 0x001047b0: ld [ %i4 + 0x10 ], %o0 0x001047b4: call 0x1048fc 0x001047b8: nop 0x001047bc: mov %o0, %i1 End of assembler dump.
reading 8192 bytes into the address 0xf00a30ec corrupts 0x00104798.
Hmmm it may be interesting to see on which device the read is being issued. Inside obp_devread add something like the following:
ucell ihandle;
ihandle = ih_to_phandle(dev_desc); printk("### phandle: " FMT_ucellx\n");
This will convert the device descriptor (which appears to be an ihandle or device instance in OF) into a phandle or package handle and display it on the console.
If you then compare the phandle with the output of "show-devs" from the Forth console then you can work out which device, and hence which driver is being used. Note that there was an issue in the SPARC64 CIF related to C argument order versus Forth stack order so you may wish to verify the order under SPARC32 aswell.
Is there an easy way to see from gdb where the both addresses are mapped to? "map?" seems to be not implemented in the OpenBIOS.
To see all of the memory allocations/deallocations and mappings then you want to set CONFIG_DEBUG_OFMEM to true in config/examples/cross-sparc32.xml and rebuild. For the low level stuff (e.g. interacting with the virtual qemu hardware) then take a look at defining CONFIG_DEBUG_MEM in arch/sparc32/lib.c and going from there.
HTH,
Mark.
Mark Cave-Ayland wrote:
Hmmm it may be interesting to see on which device the read is being issued. Inside obp_devread add something like the following:
ucell phandle;
phandle = ih_to_phandle(dev_desc); printk("### phandle: " FMT_ucellx\n", phandle);
Looks like the gremlins got into my email again. Of course what you really want is this:
ucell phandle;
phandle = ih_to_phandle(dev_desc); printk("### phandle: " FMT_ucellx\n", phandle);
HTH,
Mark.
2010/4/7 Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk:
Mark Cave-Ayland wrote:
Hmmm it may be interesting to see on which device the read is being issued. Inside obp_devread add something like the following:
ucell phandle;
phandle = ih_to_phandle(dev_desc); printk("### phandle: " FMT_ucellx\n", phandle);
Looks like the gremlins got into my email again. Of course what you really want is this:
ucell phandle;
phandle = ih_to_phandle(dev_desc); printk("### phandle: " FMT_ucellx\n", phandle);
### phandle: ffd86744 ffd86744 /packages/disk-label
Artyom Tarasenko wrote:
### phandle: ffd86744 ffd86744 /packages/disk-label
Okay. That's probably a raw disk partition which seems fairly normal.
ATB,
Mark.
2010/4/7 Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk:
Artyom Tarasenko wrote:
### phandle: ffd86744 ffd86744 /packages/disk-label
Okay. That's probably a raw disk partition which seems fairly normal.
Yes, it's a bunch of reads. The first 9 reads (f00890ec-f00a10ec) don't do any visible harm, but f00a30ec is lethal. Under OBP there is more than 30 reads after this point. Didn't count them after this point.
Artyom Tarasenko wrote:
Yes, it's a bunch of reads. The first 9 reads (f00890ec-f00a10ec) don't do any visible harm, but f00a30ec is lethal. Under OBP there is more than 30 reads after this point. Didn't count them after this point.
Well given that the same disk code for SPARC64 is reading in several megs at a time without any problems now, I think if there was an issue then it could be in one of the hardware drivers or possibly the MMU.
Wait a minute. I've just noticed that arch/sparc32 hasn't been updated to use the new libopenbios/ofmem_common.c API which will handle the physical memory allocation, virtual memory allocation and mappings for you. And this would explain why CONFIG_DEBUG_OFMEM wouldn't have actually output anything :(
I'd suggest a good starting point for you would be to first switch over to the libopenbios/ofmem_common.c API in arch/sparc32/lib.c using arch/sparc64/lib.c as a reference, and then similarly update arch/sparc32/romvec.c where appropriate. I also seem to recall that Blue had a compile time #define in Qemu that would dump the page table contents and so you can use this to verify that the OpenBIOS code is correct. With these two things in place, then you have all the debugging information you need :D
HTH,
Mark.
2010/4/9 Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk:
Artyom Tarasenko wrote:
Yes, it's a bunch of reads. The first 9 reads (f00890ec-f00a10ec) don't do any visible harm, but f00a30ec is lethal. Under OBP there is more than 30 reads after this point. Didn't count them after this point.
Well given that the same disk code for SPARC64 is reading in several megs at a time without any problems now, I think if there was an issue then it could be in one of the hardware drivers or possibly the MMU.
Wait a minute. I've just noticed that arch/sparc32 hasn't been updated to use the new libopenbios/ofmem_common.c API which will handle the physical memory allocation, virtual memory allocation and mappings for you. And this would explain why CONFIG_DEBUG_OFMEM wouldn't have actually output anything :(
I'd suggest a good starting point for you would be to first switch over to the libopenbios/ofmem_common.c API in arch/sparc32/lib.c using arch/sparc64/lib.c as a reference, and then similarly update arch/sparc32/romvec.c where appropriate.
If they are so similar, why isn't the code located somewhere in sparc-common?
I also seem to recall that Blue had a compile time #define in Qemu that would dump the page table contents and so you can use this to verify that the OpenBIOS code is correct. With these two things in place, then you have all the debugging information you need :D
Within the next months I only have time to test, not to develop/refactor.
A quick analysis has shown that obp_dumb_memalloc is probably too dumb: it maps f00aXXXX to 0104xxxx (which seems to be already mapped to 0104xxxx).
totmap[0].num_bytes is always initialized with value 2088960. Is it the size of already mappED memory? Then why does obp_dumb_memalloc decrease this amount? If it is mappABLE, then the value 2088960 seems to be quite small.
Artyom Tarasenko wrote:
I'd suggest a good starting point for you would be to first switch over to the libopenbios/ofmem_common.c API in arch/sparc32/lib.c using arch/sparc64/lib.c as a reference, and then similarly update arch/sparc32/romvec.c where appropriate.
If they are so similar, why isn't the code located somewhere in sparc-common?
Probably for two reasons: firstly the ofmem_common.c memory API is quite new, and secondly it's only a few lines and so it would probably be overkill for the job in hand.
I also seem to recall that Blue had a compile time #define in Qemu that would dump the page table contents and so you can use this to verify that the OpenBIOS code is correct. With these two things in place, then you have all the debugging information you need :D
Within the next months I only have time to test, not to develop/refactor.
A quick analysis has shown that obp_dumb_memalloc is probably too dumb: it maps f00aXXXX to 0104xxxx (which seems to be already mapped to 0104xxxx).
totmap[0].num_bytes is always initialized with value 2088960. Is it the size of already mappED memory? Then why does obp_dumb_memalloc decrease this amount? If it is mappABLE, then the value 2088960 seems to be quite small.
I don't think it would be too hard a task with the necessary romvec interface documentation (anyone know where you can get this?). All you have to do is change the existing romvec functions for simple memory alloc/free/map wrapper functions that call the existing routines in ofmem_common.c instead which are already known to work with PPC/SPARC64. Then the existing code (which from your analysis seems to be broken) can just be ripped out.
HTH,
Mark.
On 4/9/10, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Artyom Tarasenko wrote:
I'd suggest a good starting point for you would be to first switch over
to
the libopenbios/ofmem_common.c API in arch/sparc32/lib.c using arch/sparc64/lib.c as a reference, and then similarly update arch/sparc32/romvec.c where appropriate.
If they are so similar, why isn't the code located somewhere in
sparc-common?
Probably for two reasons: firstly the ofmem_common.c memory API is quite new, and secondly it's only a few lines and so it would probably be overkill for the job in hand.
I also seem to recall that Blue had a compile time #define in Qemu that would dump the page table contents
and
so you can use this to verify that the OpenBIOS code is correct. With
these
two things in place, then you have all the debugging information you
need :D
Within the next months I only have time to test, not to develop/refactor.
A quick analysis has shown that obp_dumb_memalloc is probably too dumb: it maps f00aXXXX to 0104xxxx (which seems to be already mapped to
0104xxxx).
totmap[0].num_bytes is always initialized with value 2088960. Is it the
size
of already mappED memory? Then why does obp_dumb_memalloc decrease this amount? If it is mappABLE, then the value 2088960 seems to be quite
small.
I don't think it would be too hard a task with the necessary romvec interface documentation (anyone know where you can get this?). All you
There is some information in the header file, arch/sparc32/openprom.h and how Linux uses it (arch/sparc/prom/*).
have to do is change the existing romvec functions for simple memory alloc/free/map wrapper functions that call the existing routines in ofmem_common.c instead which are already known to work with PPC/SPARC64. Then the existing code (which from your analysis seems to be broken) can just be ripped out.
Should be a good idea. There are some hacks now for Solaris/SunOS but I think this way is cleaner.
Am 07.04.2010 um 15:44 schrieb Artyom Tarasenko:
reading 8192 bytes into the address 0xf00a30ec corrupts 0x00104798.
That would seem to concur with my report of the Haiku bootloader being partially overwritten by OpenBIOS/ppc, so it likely happens somewhere in generic code.
Andreas