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", | |
46 | "Free memmory", | |
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; | |
e01402b1 | 57 | char cmdline[CL_SIZE], *ptr; |
1da177e4 | 58 | |
e1a4e469 RB |
59 | /* otherwise look in the environment */ |
60 | memsize_str = prom_getenv("memsize"); | |
61 | if (!memsize_str) { | |
36a88530 RB |
62 | printk(KERN_WARNING |
63 | "memsize not set in boot prom, set to default (32Mb)\n"); | |
e1a4e469 RB |
64 | physical_memsize = 0x02000000; |
65 | } else { | |
1da177e4 | 66 | #ifdef DEBUG |
36a88530 | 67 | pr_debug("prom_memsize = %s\n", memsize_str); |
1da177e4 | 68 | #endif |
e1a4e469 | 69 | physical_memsize = simple_strtol(memsize_str, NULL, 0); |
1da177e4 | 70 | } |
73499682 EO |
71 | |
72 | #ifdef CONFIG_CPU_BIG_ENDIAN | |
e1a4e469 RB |
73 | /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last |
74 | word of physical memory */ | |
75 | physical_memsize -= PAGE_SIZE; | |
73499682 EO |
76 | #endif |
77 | ||
e1a4e469 RB |
78 | /* Check the command line for a memsize directive that overrides |
79 | the physical/default amount */ | |
80 | strcpy(cmdline, arcs_cmdline); | |
81 | ptr = strstr(cmdline, "memsize="); | |
82 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
83 | ptr = strstr(ptr, " memsize="); | |
84 | ||
85 | if (ptr) | |
86 | memsize = memparse(ptr + 8, &ptr); | |
87 | else | |
88 | memsize = physical_memsize; | |
89 | ||
1da177e4 LT |
90 | memset(mdesc, 0, sizeof(mdesc)); |
91 | ||
92 | mdesc[0].type = yamon_dontuse; | |
93 | mdesc[0].base = 0x00000000; | |
94 | mdesc[0].size = 0x00001000; | |
95 | ||
96 | mdesc[1].type = yamon_prom; | |
97 | mdesc[1].base = 0x00001000; | |
98 | mdesc[1].size = 0x000ef000; | |
99 | ||
1da177e4 LT |
100 | /* |
101 | * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | |
102 | * south bridge and PCI access always forwarded to the ISA Bus and | |
103 | * BIOSCS# is always generated. | |
104 | * This mean that this area can't be used as DMA memory for PCI | |
105 | * devices. | |
106 | */ | |
107 | mdesc[2].type = yamon_dontuse; | |
108 | mdesc[2].base = 0x000f0000; | |
109 | mdesc[2].size = 0x00010000; | |
1da177e4 LT |
110 | |
111 | mdesc[3].type = yamon_dontuse; | |
112 | mdesc[3].base = 0x00100000; | |
fde3505c | 113 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; |
1da177e4 LT |
114 | |
115 | mdesc[4].type = yamon_free; | |
fde3505c | 116 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
1da177e4 LT |
117 | mdesc[4].size = memsize - mdesc[4].base; |
118 | ||
119 | return &mdesc[0]; | |
120 | } | |
121 | ||
49a89efb | 122 | static int __init prom_memtype_classify(unsigned int type) |
1da177e4 LT |
123 | { |
124 | switch (type) { | |
125 | case yamon_free: | |
126 | return BOOT_MEM_RAM; | |
127 | case yamon_prom: | |
128 | return BOOT_MEM_ROM_DATA; | |
129 | default: | |
130 | return BOOT_MEM_RESERVED; | |
131 | } | |
132 | } | |
133 | ||
134 | void __init prom_meminit(void) | |
135 | { | |
136 | struct prom_pmemblock *p; | |
137 | ||
138 | #ifdef DEBUG | |
36a88530 | 139 | pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); |
1da177e4 LT |
140 | p = prom_getmdesc(); |
141 | while (p->size) { | |
142 | int i = 0; | |
36a88530 RB |
143 | pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", |
144 | i, p, p->base, p->size, mtypes[p->type]); | |
1da177e4 LT |
145 | p++; |
146 | i++; | |
147 | } | |
148 | #endif | |
149 | p = prom_getmdesc(); | |
150 | ||
151 | while (p->size) { | |
152 | long type; | |
153 | unsigned long base, size; | |
154 | ||
49a89efb | 155 | type = prom_memtype_classify(p->type); |
1da177e4 LT |
156 | base = p->base; |
157 | size = p->size; | |
158 | ||
159 | add_memory_region(base, size, type); | |
160 | p++; | |
161 | } | |
162 | } | |
163 | ||
c44e8d5e | 164 | void __init prom_free_prom_memory(void) |
1da177e4 | 165 | { |
1da177e4 LT |
166 | unsigned long addr; |
167 | int i; | |
168 | ||
169 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
170 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
171 | continue; | |
172 | ||
c44e8d5e AN |
173 | addr = boot_mem_map.map[i].addr; |
174 | free_init_pages("prom memory", | |
175 | addr, addr + boot_mem_map.map[i].size); | |
1da177e4 | 176 | } |
1da177e4 | 177 | } |