| .. | .. |
|---|
| 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 |
|---|