0001
0002
0003
0004
0005
0006
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
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
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 }