[parisc-linux] Linux only see 2Gb of ram of N4k

Joel Soete soete.joel at tiscali.be
Tue Mar 23 08:07:14 MST 2004


Hi Grant,

I come back to you with more relevant info (I hope)
>I'm pretty sure it will look like this:
>RAM      Phys Address
>0-2GB -> 0-2GB
>      -> 2-4GB I/O Space (mostly PCI MMIO)
>2-4GB -> 4-6GB (courtesy of the memory controller)
>
>The N-class was the first box which has an I/O hole from 2-4GB
>physical address range. I hope Joel will be able to confirm this.
>If not, I likely have documentation to confirm this.
>
I added some more printk as follow:
in arch/parisc/kernel/inventory.c

static void __init pat_memconfig(void)
{
        unsigned long actual_len;
        struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
        struct pdc_pat_pd_addr_map_entry *mtbl_ptr;
        physmem_range_t *pmem_ptr;
        long status;
        int entries;
        unsigned long length;
        int i;

        length = (PAT_MAX_RANGES + 1) * sizeof(struct pdc_pat_pd_addr_map_entry);

        status = pdc_pat_pd_get_addr_map(&actual_len, mem_table, length,
0L);

/* JSO S */
        if ((status == PDC_OK)) {
                printk("Status == PDC_OK.\n");
                printk("Sizeof(struct pdc_pat_pd_addr_map_entry) = %d.\n",
sizeof(struct pdc_pat_pd_addr_map_entry));
                printk("actual_len = %ld.\n", actual_len);
                printk("length = %ld.\n", length);
        }
/* JSO E */
        if ((status != PDC_OK)
            || ((actual_len % sizeof(struct pdc_pat_pd_addr_map_entry)) !=
0)) {

                /* The above pdc call shouldn't fail, but, just in
                 * case, just use the PAGE0 info.
                 */

                printk("\n\n\n");
                printk(KERN_WARNING "WARNING! Could not get full memory configuration.
"
                        "All memory may not be used!\n\n\n");
                pagezero_memconfig();
                return;
        }

        entries = actual_len / sizeof(struct pdc_pat_pd_addr_map_entry);
        printk("entries = %d.\n", entries);

        if (entries > PAT_MAX_RANGES) {
                printk(KERN_WARNING "This Machine has more memory ranges
than we support!\n");
                printk(KERN_WARNING "Some memory may not be used!\n");
        }

        /* Copy information into the firmware independent pmem_ranges
         * array, skipping types we don't care about. Notice we said
         * "may" above. We'll use all the entries that were returned.
         */

        npmem_ranges = 0;
        mtbl_ptr = mem_table;
        pmem_ptr = pmem_ranges; /* Global firmware independent table */
        for (i = 0; i < entries; i++,mtbl_ptr++) {
                if (   (mtbl_ptr->entry_type != PAT_MEMORY_DESCRIPTOR)
                    || (mtbl_ptr->memory_type != PAT_MEMTYPE_MEMORY)
                    || (mtbl_ptr->pages == 0)
                    || (   (mtbl_ptr->memory_usage != PAT_MEMUSE_GENERAL)
                        && (mtbl_ptr->memory_usage != PAT_MEMUSE_GI)
                        && (mtbl_ptr->memory_usage != PAT_MEMUSE_GNI) ) )
{

                        continue;
                }

                if (npmem_ranges == MAX_PHYSMEM_RANGES) {
                        printk(KERN_WARNING "This Machine has more memory
ranges than we support!\n");
                        printk(KERN_WARNING "Some memory will not be used!\n");
                        break;
                }

                set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
                npmem_ranges++;
        }
        for (i = 0; i < entries; i++)
                printk("pmem_ranges[%d].pages = %ld.\n", i, pmem_ranges[i].pages);
        printk("npmem_ranges = %d.\n", npmem_ranges);
}

arch/parisc/mm/init.c
static void __init setup_bootmem(void)
{
[snip]
#ifndef CONFIG_DISCONTIGMEM
        /*
         * Sort the ranges. Since the number of ranges is typically
         * small, and performance is not an issue here, just do
         * a simple insertion sort.
         */

        printk("npmem_ranges = %d.(line 143)\n", npmem_ranges);
        for (i = 1; i < npmem_ranges; i++) {
                int j;

                for (j = i; j > 0; j--) {
                        unsigned long tmp;

                        if (pmem_ranges[j-1].start_pfn <
                            pmem_ranges[j].start_pfn) {

                                break;
                        }
                        tmp = pmem_ranges[j-1].start_pfn;
                        pmem_ranges[j-1].start_pfn = pmem_ranges[j].start_pfn;
                        pmem_ranges[j].start_pfn = tmp;
                        tmp = pmem_ranges[j-1].pages;
                        pmem_ranges[j-1].pages = pmem_ranges[j].pages;
                        pmem_ranges[j].pages = tmp;
                }
        }

        /*
         * Throw out ranges that are too far apart (controlled by
         * MAX_GAP). If CONFIG_DISCONTIGMEM wasn't implemented so
         * poorly, we would recommend enabling that option, but,
         * until it is fixed, this is the best way to go.
         */

        printk("npmem_ranges = %d.(line 171)\n", npmem_ranges);
        for (i = 1; i < npmem_ranges; i++) {
                printk("pmem_ranges[%d].start_pfn = %ld.\n", i-1, pmem_ranges[i-1].pages);
                printk("pmem_ranges[%d].pages = %ld.\n", i-1, pmem_ranges[i-1].pages);
                printk("pmem_ranges[%d].start_pfn = %ld.\n", i, pmem_ranges[i].pages);
                printk("MAX_GAP = %ld.\n", MAX_GAP);
                if (pmem_ranges[i].start_pfn -
                        (pmem_ranges[i-1].start_pfn +
                         pmem_ranges[i-1].pages) > MAX_GAP) {
                        npmem_ranges = i;<=====================[ref1.]
                        break;
                }
        }
#endif

        printk("npmem_ranges = %d.(line 186)\n", npmem_ranges);
        if (npmem_ranges > 1) {
[snip]

<==== return by pat_memconfig() ====>
Status == PDC_OK.
Sizeof(struct pdc_pat_pd_addr_map_entry) = 32.
actual_len = 64.
length = 1056.
entries = 2.
pmem_ranges[0].pages = 524288.
pmem_ranges[1].pages = 524288.
npmem_ranges = 2.

So pat_memconfig() returns well 2 entries of 2Gb Ok

<==== return by setup_bootmem() ====>
npmem_ranges = 2.(line 143)
npmem_ranges = 2.(line 171)
pmem_ranges[0].start_pfn = 524288.
pmem_ranges[0].pages = 524288.
pmem_ranges[1].start_pfn = 524288.
MAX_GAP = 262144.
npmem_ranges = 1.(line 186)
pmem_ranges[0].pages = 524288.

So here only one entry is scan because of condition ([ref1]) but I have no
clue of the actual meaning of this condition. Thanks in advance for info
:)

RSize = 2147483648.
Total Memory: 2048 Mb
On node 0 totalpages: 524288

Thanks,
    Joel


----------------------------------------------------------------------------------------
Tiscali ADSL: 35 €/mois, la meilleure offre du marché!
http://reg.tiscali.be/default.asp?lg=fr





More information about the parisc-linux mailing list