]>
Commit | Line | Data |
---|---|---|
c78cbf49 RB |
1 | /* |
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | |
3 | * | |
4 | * This program is free software; you can distribute it and/or modify it | |
5 | * under the terms of the GNU General Public License (Version 2) as | |
6 | * published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope it will be useful, but WITHOUT | |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
11 | * for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License along | |
14 | * with this program; if not, write to the Free Software Foundation, Inc., | |
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
16 | * | |
17 | */ | |
18 | #include <linux/init.h> | |
19 | #include <linux/mm.h> | |
20 | #include <linux/bootmem.h> | |
21 | ||
22 | #include <asm/bootinfo.h> | |
23 | #include <asm/page.h> | |
24 | ||
25 | #include <asm/mips-boards/prom.h> | |
26 | ||
27 | /*#define DEBUG*/ | |
28 | ||
29 | enum simmem_memtypes { | |
30 | simmem_reserved = 0, | |
31 | simmem_free, | |
32 | }; | |
33 | struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | |
34 | ||
35 | #ifdef DEBUG | |
36 | static char *mtypes[3] = { | |
37 | "SIM reserved memory", | |
38 | "SIM free memory", | |
39 | }; | |
40 | #endif | |
41 | ||
42 | /* References to section boundaries */ | |
43 | extern char _end; | |
44 | ||
c78cbf49 RB |
45 | struct prom_pmemblock * __init prom_getmdesc(void) |
46 | { | |
47 | unsigned int memsize; | |
48 | ||
49 | memsize = 0x02000000; | |
50 | prom_printf("Setting default memory size 0x%08x\n", memsize); | |
51 | ||
52 | memset(mdesc, 0, sizeof(mdesc)); | |
53 | ||
54 | mdesc[0].type = simmem_reserved; | |
55 | mdesc[0].base = 0x00000000; | |
56 | mdesc[0].size = 0x00001000; | |
57 | ||
58 | mdesc[1].type = simmem_free; | |
59 | mdesc[1].base = 0x00001000; | |
60 | mdesc[1].size = 0x000ff000; | |
61 | ||
62 | mdesc[2].type = simmem_reserved; | |
63 | mdesc[2].base = 0x00100000; | |
22a9835c | 64 | mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base; |
c78cbf49 RB |
65 | |
66 | mdesc[3].type = simmem_free; | |
22a9835c | 67 | mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end)); |
c78cbf49 RB |
68 | mdesc[3].size = memsize - mdesc[3].base; |
69 | ||
70 | return &mdesc[0]; | |
71 | } | |
72 | ||
73 | static int __init prom_memtype_classify (unsigned int type) | |
74 | { | |
75 | switch (type) { | |
76 | case simmem_free: | |
77 | return BOOT_MEM_RAM; | |
78 | case simmem_reserved: | |
79 | default: | |
80 | return BOOT_MEM_RESERVED; | |
81 | } | |
82 | } | |
83 | ||
84 | void __init prom_meminit(void) | |
85 | { | |
86 | struct prom_pmemblock *p; | |
87 | ||
88 | p = prom_getmdesc(); | |
89 | ||
90 | while (p->size) { | |
91 | long type; | |
92 | unsigned long base, size; | |
93 | ||
94 | type = prom_memtype_classify (p->type); | |
95 | base = p->base; | |
96 | size = p->size; | |
97 | ||
98 | add_memory_region(base, size, type); | |
99 | p++; | |
100 | } | |
101 | } | |
102 | ||
103 | unsigned long __init prom_free_prom_memory(void) | |
104 | { | |
105 | int i; | |
106 | unsigned long freed = 0; | |
107 | unsigned long addr; | |
108 | ||
109 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
110 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
111 | continue; | |
112 | ||
113 | addr = boot_mem_map.map[i].addr; | |
114 | while (addr < boot_mem_map.map[i].addr | |
115 | + boot_mem_map.map[i].size) { | |
116 | ClearPageReserved(virt_to_page(__va(addr))); | |
7835e98b | 117 | init_page_count(virt_to_page(__va(addr))); |
c78cbf49 RB |
118 | free_page((unsigned long)__va(addr)); |
119 | addr += PAGE_SIZE; | |
120 | freed += PAGE_SIZE; | |
121 | } | |
122 | } | |
123 | printk("Freeing prom memory: %ldkb freed\n", freed >> 10); | |
124 | ||
125 | return freed; | |
126 | } |