.. | .. |
---|
11 | 11 | #include <linux/init.h> |
---|
12 | 12 | #include <linux/export.h> |
---|
13 | 13 | #include <linux/kernel.h> |
---|
| 14 | +#include <linux/memblock.h> |
---|
14 | 15 | #include <linux/spinlock.h> |
---|
15 | 16 | |
---|
16 | 17 | #include <asm/io.h> |
---|
.. | .. |
---|
40 | 41 | return bank % 2 ? res & 0xffff : res >> 16; |
---|
41 | 42 | } |
---|
42 | 43 | |
---|
43 | | -struct mem { |
---|
44 | | - unsigned long addr; |
---|
45 | | - unsigned long size; |
---|
46 | | -}; |
---|
47 | | - |
---|
| 44 | +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_32BIT) |
---|
| 45 | +static void __init probe_memory(void) |
---|
| 46 | +{ |
---|
| 47 | + /* prom detects all usable memory */ |
---|
| 48 | +} |
---|
| 49 | +#else |
---|
48 | 50 | /* |
---|
49 | | - * Detect installed memory, do some sanity checks and notify kernel about it |
---|
| 51 | + * Detect installed memory, which PROM misses |
---|
50 | 52 | */ |
---|
51 | 53 | static void __init probe_memory(void) |
---|
52 | 54 | { |
---|
53 | | - int i, j, found, cnt = 0; |
---|
54 | | - struct mem bank[4]; |
---|
55 | | - struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}}; |
---|
| 55 | + unsigned long addr, size; |
---|
| 56 | + int i; |
---|
56 | 57 | |
---|
57 | 58 | printk(KERN_INFO "MC: Probing memory configuration:\n"); |
---|
58 | | - for (i = 0; i < ARRAY_SIZE(bank); i++) { |
---|
| 59 | + for (i = 0; i < 4; i++) { |
---|
59 | 60 | unsigned int tmp = get_bank_config(i); |
---|
60 | 61 | if (!(tmp & SGIMC_MCONFIG_BVALID)) |
---|
61 | 62 | continue; |
---|
62 | 63 | |
---|
63 | | - bank[cnt].size = get_bank_size(tmp); |
---|
64 | | - bank[cnt].addr = get_bank_addr(tmp); |
---|
| 64 | + size = get_bank_size(tmp); |
---|
| 65 | + addr = get_bank_addr(tmp); |
---|
65 | 66 | printk(KERN_INFO " bank%d: %3ldM @ %08lx\n", |
---|
66 | | - i, bank[cnt].size / 1024 / 1024, bank[cnt].addr); |
---|
67 | | - cnt++; |
---|
| 67 | + i, size / 1024 / 1024, addr); |
---|
| 68 | + |
---|
| 69 | + if (addr >= SGIMC_SEG1_BADDR) |
---|
| 70 | + memblock_add(addr, size); |
---|
68 | 71 | } |
---|
69 | | - |
---|
70 | | - /* And you thought bubble sort is dead algorithm... */ |
---|
71 | | - do { |
---|
72 | | - unsigned long addr, size; |
---|
73 | | - |
---|
74 | | - found = 0; |
---|
75 | | - for (i = 1; i < cnt; i++) |
---|
76 | | - if (bank[i-1].addr > bank[i].addr) { |
---|
77 | | - addr = bank[i].addr; |
---|
78 | | - size = bank[i].size; |
---|
79 | | - bank[i].addr = bank[i-1].addr; |
---|
80 | | - bank[i].size = bank[i-1].size; |
---|
81 | | - bank[i-1].addr = addr; |
---|
82 | | - bank[i-1].size = size; |
---|
83 | | - found = 1; |
---|
84 | | - } |
---|
85 | | - } while (found); |
---|
86 | | - |
---|
87 | | - /* Figure out how are memory banks mapped into spaces */ |
---|
88 | | - for (i = 0; i < cnt; i++) { |
---|
89 | | - found = 0; |
---|
90 | | - for (j = 0; j < ARRAY_SIZE(space) && !found; j++) |
---|
91 | | - if (space[j].addr + space[j].size == bank[i].addr) { |
---|
92 | | - space[j].size += bank[i].size; |
---|
93 | | - found = 1; |
---|
94 | | - } |
---|
95 | | - /* There is either hole or overlapping memory */ |
---|
96 | | - if (!found) |
---|
97 | | - printk(KERN_CRIT "MC: Memory configuration mismatch " |
---|
98 | | - "(%08lx), expect Bus Error soon\n", |
---|
99 | | - bank[i].addr); |
---|
100 | | - } |
---|
101 | | - |
---|
102 | | - for (i = 0; i < ARRAY_SIZE(space); i++) |
---|
103 | | - if (space[i].size) |
---|
104 | | - add_memory_region(space[i].addr, space[i].size, |
---|
105 | | - BOOT_MEM_RAM); |
---|
106 | 72 | } |
---|
| 73 | +#endif |
---|
107 | 74 | |
---|
108 | 75 | void __init sgimc_init(void) |
---|
109 | 76 | { |
---|
.. | .. |
---|
205 | 172 | probe_memory(); |
---|
206 | 173 | } |
---|
207 | 174 | |
---|
208 | | -void __init prom_meminit(void) {} |
---|
209 | | -void __init prom_free_prom_memory(void) |
---|
210 | | -{ |
---|
211 | 175 | #ifdef CONFIG_SGI_IP28 |
---|
| 176 | +void __init prom_cleanup(void) |
---|
| 177 | +{ |
---|
212 | 178 | u32 mconfig1; |
---|
213 | 179 | unsigned long flags; |
---|
214 | 180 | spinlock_t lock; |
---|
.. | .. |
---|
233 | 199 | sgimc->mconfig1 = mconfig1; |
---|
234 | 200 | iob(); |
---|
235 | 201 | spin_unlock_irqrestore(&lock, flags); |
---|
236 | | -#endif |
---|
237 | 202 | } |
---|
| 203 | +#endif |
---|