[linux-cirrus] Re: bootmem_init_node failure with 64M TS-7250

On Thu, Dec 28, 2006 at 08:33:18PM -0500, Charles Moschel wrote:

> Hi Folks --
> 
> I've been trying to use 2.6.19 (plus some of Lennert's ep93xx patches)
> on a TS-7250 with 64M ram, but the boot hangs after "...done, Booting
> the kernel" message.  

I get asked this question in private a lot.  :-)


> It seems that the higher banks are wired in the middle of the kernel
> address space.  Is this supposed to work, or should I get used to having
> only 32M on this board? 

(The upper banks on the 64M TS7250 are at 0xe0000000 _physical_, which
isn't the same thing as the c0000000..ffffffff _virtual_ address range.)


> Details I've found so far:
> 
> The processor is an EP9302, and the board has (8) 8M banks ram at the
> following physical locations:
>  0x00000000
>  0x01000000
>  0x04000000
>  0x05000000
>  0xe0000000
>  0xe1000000
>  0xe4000000
>  0xe5000000
> 
> Booting with four mem=8M@ (lower banks) on the command line works OK,
> but only with 32M of course.  Adding any one of the single higher
> 0xex000000 banks results in a hang.

The problem here is that Linux 2.6 ep93xx port is somewhat naive and
expects all RAM to be within a 1G physical address range.  This isn't
always true on ep93xx hardware (such as your board), but it _is_ true
for all ep93xx hardware I have access to (for example, I have the 32M
variant of the TS7250), so I never fixed the problem, even though Linux
supports not having all RAM within a 1G range just fine.


> My first suspect was redboot and ATAGs, but passed ATAGs look ok (I
> added a printk in parse_tag_mem32(), and defined printascii).
> 
> The bootlog shows that it fails in bootmem_init_node --> map_memory_bank
> --> create_mapping on the 5th pass, when the md->virtual < TASK_SIZE
> triggers:
> 
> if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
>                 printk(KERN_WARNING "BUG: not creating mapping for "
>                        "0x%08llx at 0x%08lx in user region\n",
>                        __pfn_to_phys((u64)md->pfn), md->virtual);
> 
> Should I try a DISCONTIGMEM or SPARSEMEM build?

Yes, this is exactly what needs to be done to fix the problem in a
generic way, but it does involve writing a bit of code.

Another option _might_ be to set PHYS_OFFSET to e0000000, and tell
Redboot to load the kernel at 0xe0008000.  This will likely mess up ATAG
passing (so you'll have to comment out the boot_params line in ts7250.c,
hardcode the machine ID and pass mem= parameters for every memory block
by hand), but it'll cause physical RAM to be within a 1G range (e0000000
.. 1fffffff, (ab)using 4G address wrap) and might just work.


> <4>Parse_tag_mem32: adding memory bank 0x00000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0x01000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0x04000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0x05000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0xe0000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0xe1000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0xe4000000 size 8192KB
> <4>Parse_tag_mem32: adding memory bank 0xe5000000 size 8192KB
> Memory policy: ECC disabled, Data cache writeback
> <4>BUG: not creating mapping for 0xe0000000 at 0xa0000000 in user region
> <4>BUG: not creating mapping for 0xe1000000 at 0xa1000000 in user region
> <4>BUG: not creating mapping for 0xe4000000 at 0xa4000000 in user region
> <4>BUG: not creating mapping for 0xe5000000 at 0xa5000000 in user region

(The kernel mapped the 0....... physical address range to c.......
virtual, and if you use that rule (virtual = physical + 0xc0000000)
for the e....... physical address range, you end up with a.......,
which is under the c0000000-ffffffff kernel virtual area.)

Other related posts: