]>
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 | ||
45 | #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) | |
46 | ||
47 | ||
48 | struct prom_pmemblock * __init prom_getmdesc(void) | |
49 | { | |
50 | unsigned int memsize; | |
51 | ||
52 | memsize = 0x02000000; | |
53 | prom_printf("Setting default memory size 0x%08x\n", memsize); | |
54 | ||
55 | memset(mdesc, 0, sizeof(mdesc)); | |
56 | ||
57 | mdesc[0].type = simmem_reserved; | |
58 | mdesc[0].base = 0x00000000; | |
59 | mdesc[0].size = 0x00001000; | |
60 | ||
61 | mdesc[1].type = simmem_free; | |
62 | mdesc[1].base = 0x00001000; | |
63 | mdesc[1].size = 0x000ff000; | |
64 | ||
65 | mdesc[2].type = simmem_reserved; | |
66 | mdesc[2].base = 0x00100000; | |
67 | mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base; | |
68 | ||
69 | mdesc[3].type = simmem_free; | |
70 | mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end)); | |
71 | mdesc[3].size = memsize - mdesc[3].base; | |
72 | ||
73 | return &mdesc[0]; | |
74 | } | |
75 | ||
76 | static int __init prom_memtype_classify (unsigned int type) | |
77 | { | |
78 | switch (type) { | |
79 | case simmem_free: | |
80 | return BOOT_MEM_RAM; | |
81 | case simmem_reserved: | |
82 | default: | |
83 | return BOOT_MEM_RESERVED; | |
84 | } | |
85 | } | |
86 | ||
87 | void __init prom_meminit(void) | |
88 | { | |
89 | struct prom_pmemblock *p; | |
90 | ||
91 | p = prom_getmdesc(); | |
92 | ||
93 | while (p->size) { | |
94 | long type; | |
95 | unsigned long base, size; | |
96 | ||
97 | type = prom_memtype_classify (p->type); | |
98 | base = p->base; | |
99 | size = p->size; | |
100 | ||
101 | add_memory_region(base, size, type); | |
102 | p++; | |
103 | } | |
104 | } | |
105 | ||
106 | unsigned long __init prom_free_prom_memory(void) | |
107 | { | |
108 | int i; | |
109 | unsigned long freed = 0; | |
110 | unsigned long addr; | |
111 | ||
112 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
113 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
114 | continue; | |
115 | ||
116 | addr = boot_mem_map.map[i].addr; | |
117 | while (addr < boot_mem_map.map[i].addr | |
118 | + boot_mem_map.map[i].size) { | |
119 | ClearPageReserved(virt_to_page(__va(addr))); | |
7835e98b | 120 | init_page_count(virt_to_page(__va(addr))); |
c78cbf49 RB |
121 | free_page((unsigned long)__va(addr)); |
122 | addr += PAGE_SIZE; | |
123 | freed += PAGE_SIZE; | |
124 | } | |
125 | } | |
126 | printk("Freeing prom memory: %ldkb freed\n", freed >> 10); | |
127 | ||
128 | return freed; | |
129 | } |