Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* memory.c: Prom routine for acquiring various bits of information
0003  *           about RAM on the machine, both virtual and physical.
0004  *
0005  * Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
0006  * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/sort.h>
0011 #include <linux/init.h>
0012 
0013 #include <asm/openprom.h>
0014 #include <asm/oplib.h>
0015 #include <asm/page.h>
0016 
0017 static int __init prom_meminit_v0(void)
0018 {
0019     struct linux_mlist_v0 *p;
0020     int index;
0021 
0022     index = 0;
0023     for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) {
0024         sp_banks[index].base_addr = (unsigned long) p->start_adr;
0025         sp_banks[index].num_bytes = p->num_bytes;
0026         index++;
0027     }
0028 
0029     return index;
0030 }
0031 
0032 static int __init prom_meminit_v2(void)
0033 {
0034     struct linux_prom_registers reg[64];
0035     phandle node;
0036     int size, num_ents, i;
0037 
0038     node = prom_searchsiblings(prom_getchild(prom_root_node), "memory");
0039     size = prom_getproperty(node, "available", (char *) reg, sizeof(reg));
0040     num_ents = size / sizeof(struct linux_prom_registers);
0041 
0042     for (i = 0; i < num_ents; i++) {
0043         sp_banks[i].base_addr = reg[i].phys_addr;
0044         sp_banks[i].num_bytes = reg[i].reg_size;
0045     }
0046 
0047     return num_ents;
0048 }
0049 
0050 static int sp_banks_cmp(const void *a, const void *b)
0051 {
0052     const struct sparc_phys_banks *x = a, *y = b;
0053 
0054     if (x->base_addr > y->base_addr)
0055         return 1;
0056     if (x->base_addr < y->base_addr)
0057         return -1;
0058     return 0;
0059 }
0060 
0061 /* Initialize the memory lists based upon the prom version. */
0062 void __init prom_meminit(void)
0063 {
0064     int i, num_ents = 0;
0065 
0066     switch (prom_vers) {
0067     case PROM_V0:
0068         num_ents = prom_meminit_v0();
0069         break;
0070 
0071     case PROM_V2:
0072     case PROM_V3:
0073         num_ents = prom_meminit_v2();
0074         break;
0075 
0076     default:
0077         break;
0078     }
0079     sort(sp_banks, num_ents, sizeof(struct sparc_phys_banks),
0080          sp_banks_cmp, NULL);
0081 
0082     /* Sentinel.  */
0083     sp_banks[num_ents].base_addr = 0xdeadbeef;
0084     sp_banks[num_ents].num_bytes = 0;
0085 
0086     for (i = 0; i < num_ents; i++)
0087         sp_banks[i].num_bytes &= PAGE_MASK;
0088 }