Commit | Line | Data |
---|---|---|
a3a0f8c8 DV |
1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | |
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | |
4 | * Portions copyright (C) 2009 Cisco Systems, Inc. | |
5 | * | |
6 | * This program is free software; you can distribute it and/or modify it | |
7 | * under the terms of the GNU General Public License (Version 2) as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 | * for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
18 | * | |
19 | * Apparently originally from arch/mips/malta-memory.c. Modified to work | |
20 | * with the PowerTV bootloader. | |
21 | */ | |
22 | #include <linux/init.h> | |
23 | #include <linux/mm.h> | |
24 | #include <linux/bootmem.h> | |
25 | #include <linux/pfn.h> | |
26 | #include <linux/string.h> | |
27 | ||
28 | #include <asm/bootinfo.h> | |
29 | #include <asm/page.h> | |
30 | #include <asm/sections.h> | |
31 | ||
32 | #include <asm/mips-boards/prom.h> | |
33 | ||
34 | #include "init.h" | |
35 | ||
36 | /* Memory constants */ | |
37 | #define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ | |
38 | #define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ | |
39 | #define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize provided */ | |
40 | #define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */ | |
41 | #define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for bldr */ | |
42 | #define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ | |
43 | #define PHYS_MEM_START 0x10000000 /* Start of physical memory */ | |
44 | ||
a3a0f8c8 DV |
45 | char __initdata cmdline[COMMAND_LINE_SIZE]; |
46 | ||
47 | void __init prom_meminit(void) | |
48 | { | |
49 | char *memsize_str; | |
50 | unsigned long memsize = 0; | |
51 | unsigned int physend; | |
52 | char *ptr; | |
53 | int low_mem; | |
54 | int high_mem; | |
55 | ||
56 | /* Check the command line first for a memsize directive */ | |
57 | strcpy(cmdline, arcs_cmdline); | |
58 | ptr = strstr(cmdline, "memsize="); | |
59 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
60 | ptr = strstr(ptr, " memsize="); | |
61 | ||
62 | if (ptr) { | |
63 | memsize = memparse(ptr + 8, &ptr); | |
64 | } else { | |
65 | /* otherwise look in the environment */ | |
66 | memsize_str = prom_getenv("memsize"); | |
67 | ||
68 | if (memsize_str != NULL) { | |
69 | pr_info("prom memsize = %s\n", memsize_str); | |
70 | memsize = simple_strtol(memsize_str, NULL, 0); | |
71 | } | |
72 | ||
73 | if (memsize == 0) { | |
74 | if (_prom_memsize != 0) { | |
75 | memsize = _prom_memsize; | |
76 | pr_info("_prom_memsize = 0x%lx\n", memsize); | |
77 | /* add in memory that the bootloader doesn't | |
78 | * report */ | |
79 | memsize += BOOT_MEM_SIZE; | |
80 | } else { | |
81 | memsize = DEFAULT_MEMSIZE; | |
82 | pr_info("Memsize not passed by bootloader, " | |
83 | "defaulting to 0x%lx\n", memsize); | |
84 | } | |
85 | } | |
86 | } | |
87 | ||
a3a0f8c8 DV |
88 | physend = PFN_ALIGN(&_end) - 0x80000000; |
89 | if (memsize > LOW_MEM_MAX) { | |
90 | low_mem = LOW_MEM_MAX; | |
91 | high_mem = memsize - low_mem; | |
92 | } else { | |
93 | low_mem = memsize; | |
94 | high_mem = 0; | |
95 | } | |
96 | ||
97 | /* | |
98 | * TODO: We will use the hard code for memory configuration until | |
99 | * the bootloader releases their device tree to us. | |
100 | */ | |
101 | /* | |
102 | * Add the memory reserved for use by the bootloader to the | |
103 | * memory map. | |
104 | */ | |
105 | add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE, | |
106 | BOOT_MEM_RESERVED); | |
107 | #ifdef CONFIG_HIGHMEM_256_128 | |
108 | /* | |
109 | * Add memory in low for general use by the kernel and its friends | |
110 | * (like drivers, applications, etc). | |
111 | */ | |
112 | add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, | |
113 | LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); | |
114 | /* | |
115 | * Add the memory reserved for reset vector. | |
116 | */ | |
117 | add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); | |
118 | /* | |
119 | * Add the memory reserved. | |
120 | */ | |
121 | add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED); | |
122 | /* | |
123 | * Add memory in high for general use by the kernel and its friends | |
124 | * (like drivers, applications, etc). | |
125 | * | |
126 | * 75MB is reserved for devices which are using the memory in high. | |
127 | */ | |
128 | add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), | |
129 | BOOT_MEM_RAM); | |
130 | #elif defined CONFIG_HIGHMEM_128_128 | |
131 | /* | |
132 | * Add memory in low for general use by the kernel and its friends | |
133 | * (like drivers, applications, etc). | |
134 | */ | |
135 | add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, | |
136 | MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); | |
137 | /* | |
138 | * Add the memory reserved. | |
139 | */ | |
140 | add_memory_region(PHYS_MEM_START + MEBIBYTE(128), | |
141 | MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED); | |
142 | /* | |
143 | * Add memory in high for general use by the kernel and its friends | |
144 | * (like drivers, applications, etc). | |
145 | * | |
146 | * 75MB is reserved for devices which are using the memory in high. | |
147 | */ | |
148 | add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), | |
149 | BOOT_MEM_RAM); | |
150 | #else | |
151 | /* Add low memory regions for either: | |
152 | * - no-highmemory configuration case -OR- | |
153 | * - highmemory "HIGHMEM_LOWBANK_ONLY" case | |
154 | */ | |
155 | /* | |
156 | * Add memory for general use by the kernel and its friends | |
157 | * (like drivers, applications, etc). | |
158 | */ | |
159 | add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, | |
160 | low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); | |
161 | /* | |
162 | * Add the memory reserved for reset vector. | |
163 | */ | |
164 | add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); | |
165 | #endif | |
166 | } | |
167 | ||
168 | void __init prom_free_prom_memory(void) | |
169 | { | |
170 | unsigned long addr; | |
171 | int i; | |
172 | ||
173 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
174 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
175 | continue; | |
176 | ||
177 | addr = boot_mem_map.map[i].addr; | |
178 | free_init_pages("prom memory", | |
179 | addr, addr + boot_mem_map.map[i].size); | |
180 | } | |
181 | } |