Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | |
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | |
4 | * | |
5 | * This program is free software; you can distribute it and/or modify it | |
6 | * under the terms of the GNU General Public License (Version 2) as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 | * for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along | |
15 | * with this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
17 | * | |
18 | * PROM library functions for acquiring/using memory descriptors given to | |
19 | * us from the YAMON. | |
20 | */ | |
1da177e4 LT |
21 | #include <linux/init.h> |
22 | #include <linux/mm.h> | |
23 | #include <linux/bootmem.h> | |
fde3505c | 24 | #include <linux/pfn.h> |
e01402b1 | 25 | #include <linux/string.h> |
1da177e4 LT |
26 | |
27 | #include <asm/bootinfo.h> | |
28 | #include <asm/page.h> | |
9c1f1257 | 29 | #include <asm/sections.h> |
1da177e4 LT |
30 | |
31 | #include <asm/mips-boards/prom.h> | |
32 | ||
33 | /*#define DEBUG*/ | |
34 | ||
35 | enum yamon_memtypes { | |
36 | yamon_dontuse, | |
37 | yamon_prom, | |
38 | yamon_free, | |
39 | }; | |
ddaf5740 | 40 | static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; |
1da177e4 LT |
41 | |
42 | #ifdef DEBUG | |
43 | static char *mtypes[3] = { | |
44 | "Dont use memory", | |
45 | "YAMON PROM memory", | |
b595076a | 46 | "Free memory", |
1da177e4 LT |
47 | }; |
48 | #endif | |
49 | ||
e1a4e469 RB |
50 | /* determined physical memory size, not overridden by command line args */ |
51 | unsigned long physical_memsize = 0L; | |
52 | ||
ddaf5740 | 53 | static struct prom_pmemblock * __init prom_getmdesc(void) |
1da177e4 LT |
54 | { |
55 | char *memsize_str; | |
56 | unsigned int memsize; | |
c4304529 | 57 | char *ptr; |
7580c9c3 | 58 | static char cmdline[COMMAND_LINE_SIZE] __initdata; |
1da177e4 | 59 | |
e1a4e469 RB |
60 | /* otherwise look in the environment */ |
61 | memsize_str = prom_getenv("memsize"); | |
62 | if (!memsize_str) { | |
36a88530 RB |
63 | printk(KERN_WARNING |
64 | "memsize not set in boot prom, set to default (32Mb)\n"); | |
e1a4e469 RB |
65 | physical_memsize = 0x02000000; |
66 | } else { | |
1da177e4 | 67 | #ifdef DEBUG |
36a88530 | 68 | pr_debug("prom_memsize = %s\n", memsize_str); |
1da177e4 | 69 | #endif |
e1a4e469 | 70 | physical_memsize = simple_strtol(memsize_str, NULL, 0); |
1da177e4 | 71 | } |
73499682 EO |
72 | |
73 | #ifdef CONFIG_CPU_BIG_ENDIAN | |
e1a4e469 RB |
74 | /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last |
75 | word of physical memory */ | |
76 | physical_memsize -= PAGE_SIZE; | |
73499682 EO |
77 | #endif |
78 | ||
e1a4e469 RB |
79 | /* Check the command line for a memsize directive that overrides |
80 | the physical/default amount */ | |
81 | strcpy(cmdline, arcs_cmdline); | |
82 | ptr = strstr(cmdline, "memsize="); | |
83 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
84 | ptr = strstr(ptr, " memsize="); | |
85 | ||
86 | if (ptr) | |
87 | memsize = memparse(ptr + 8, &ptr); | |
88 | else | |
89 | memsize = physical_memsize; | |
90 | ||
1da177e4 LT |
91 | memset(mdesc, 0, sizeof(mdesc)); |
92 | ||
93 | mdesc[0].type = yamon_dontuse; | |
94 | mdesc[0].base = 0x00000000; | |
95 | mdesc[0].size = 0x00001000; | |
96 | ||
97 | mdesc[1].type = yamon_prom; | |
98 | mdesc[1].base = 0x00001000; | |
99 | mdesc[1].size = 0x000ef000; | |
100 | ||
1da177e4 LT |
101 | /* |
102 | * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | |
103 | * south bridge and PCI access always forwarded to the ISA Bus and | |
104 | * BIOSCS# is always generated. | |
105 | * This mean that this area can't be used as DMA memory for PCI | |
106 | * devices. | |
107 | */ | |
108 | mdesc[2].type = yamon_dontuse; | |
109 | mdesc[2].base = 0x000f0000; | |
110 | mdesc[2].size = 0x00010000; | |
1da177e4 LT |
111 | |
112 | mdesc[3].type = yamon_dontuse; | |
113 | mdesc[3].base = 0x00100000; | |
fde3505c | 114 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; |
1da177e4 LT |
115 | |
116 | mdesc[4].type = yamon_free; | |
fde3505c | 117 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
1da177e4 LT |
118 | mdesc[4].size = memsize - mdesc[4].base; |
119 | ||
120 | return &mdesc[0]; | |
121 | } | |
122 | ||
49a89efb | 123 | static int __init prom_memtype_classify(unsigned int type) |
1da177e4 LT |
124 | { |
125 | switch (type) { | |
126 | case yamon_free: | |
127 | return BOOT_MEM_RAM; | |
128 | case yamon_prom: | |
129 | return BOOT_MEM_ROM_DATA; | |
130 | default: | |
131 | return BOOT_MEM_RESERVED; | |
132 | } | |
133 | } | |
134 | ||
135 | void __init prom_meminit(void) | |
136 | { | |
137 | struct prom_pmemblock *p; | |
138 | ||
139 | #ifdef DEBUG | |
36a88530 | 140 | pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); |
1da177e4 LT |
141 | p = prom_getmdesc(); |
142 | while (p->size) { | |
143 | int i = 0; | |
36a88530 RB |
144 | pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", |
145 | i, p, p->base, p->size, mtypes[p->type]); | |
1da177e4 LT |
146 | p++; |
147 | i++; | |
148 | } | |
149 | #endif | |
150 | p = prom_getmdesc(); | |
151 | ||
152 | while (p->size) { | |
153 | long type; | |
154 | unsigned long base, size; | |
155 | ||
49a89efb | 156 | type = prom_memtype_classify(p->type); |
1da177e4 LT |
157 | base = p->base; |
158 | size = p->size; | |
159 | ||
160 | add_memory_region(base, size, type); | |
161 | p++; | |
162 | } | |
163 | } | |
164 | ||
c44e8d5e | 165 | void __init prom_free_prom_memory(void) |
1da177e4 | 166 | { |
1da177e4 LT |
167 | unsigned long addr; |
168 | int i; | |
169 | ||
170 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
171 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
172 | continue; | |
173 | ||
c44e8d5e AN |
174 | addr = boot_mem_map.map[i].addr; |
175 | free_init_pages("prom memory", | |
176 | addr, addr + boot_mem_map.map[i].size); | |
1da177e4 | 177 | } |
1da177e4 | 178 | } |