On 02/04/13 22:37, Artyom Tarasenko wrote:
Ah I think I may see the bug here - what if you change arch/sparc32/lib.c line 276 in obp_memalloc() from:
virt = ofmem_claim_virt(pointer2cell(va), size, 0);
to:
virt = ofmem_claim_virt(pointer2cell(va), size, align);
Does that fix the bug for you?
At least, it seems to die some instructions later, thanks! Will debug more. Does it mean that obp_memalloc is actually using the first argument just as a hint? As the OpenSolaris header suggests?
(goes away and tests)
Hmmmm I'm not sure that does the right thing as the change causes my Solaris 8 boot to crash. Basically if align is not set to zero then the virtual address is ignored, and OFMEM simply allocates a chunk of memory on the specified alignment. From my boot here with this change:
Breakpoint 1, obp_memalloc (va=0xf0040000 <Address 0xf0040000 out of bounds>, size=262144, align=262144) at /home/build/src/openbios/openbios-git/openbios-devel/arch/sparc32/lib.c:273 273 phys = ofmem_claim_phys(-1, size, align); (gdb) p/x align $1 = 0x40000 (gdb) next 276 virt = ofmem_claim_virt(pointer2cell(va), size, align); (gdb) p/x phys $2 = 0x6f40000 (gdb) next 279 ofmem_map(phys, virt, size, ofmem_arch_default_translation_mode(phys)); (gdb) p/x virt $3 = 0xffc40000 (gdb) next 281 return cell2pointer(virt); (gdb) p/x virt $4 = 0xffc40000 (gdb) next 282 } (gdb) 0x001134e8 in ?? () (gdb) cont Continuing. Remote connection closed
So it would seem that the caller is definitely expecting to get a VA of 0xf0040000 back. In fact looking at http://fxr.watson.org/fxr/source/sun4/os/startup.c?v=OPENSOLARIS#L818 the caller only accepts the same VA being returned as an indication of success.
This does remind me of a problem on SPARC64 where we get warnings from the bootloader because we are trying to reallocate the same region. Perhaps the right question to ask is what should the behaviour be if a region is allocated twice? For example, what should happen in this case below:
virt1 = ofmem_claim(0xf0004000, 0x2000, 0); virt2 = ofmem_claim(0xf0004000, 0x1000, 0);
If the virtual address 0xf0004000 is already claimed and mapped, should the old mapping be completely removed, or would we have to do something more complex such as split the mapped region into a new physical region and remap the first half of the split virtual region to the new physical region?
Also for reference, can you post a tar.gz of your output with both CONFIG_DEBUG_OBP and CONFIG_DEBUG_OFMEM enabled for the build (but without my modification) so we can see the duplicate memalloc?
ATB,
Mark.