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#include <asm/mach-powertv/asic.h> 34#include <asm/mach-powertv/ioremap.h> 35 36#include "init.h" 37 38/* Memory constants */ 39#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ 40#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ 41#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */ 42 43#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ 44#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */ 45 46#define LOW_MEM_END 0x20000000 /* Highest low memory address */ 47#define BLDR_ALIAS 0x10000000 /* Bootloader address */ 48#define RV_PHYS 0x1fc00000 /* Reset vector address */ 49#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */ 50 51/* 52 * Very low-level conversion from processor physical address to device 53 * DMA address for the first bank of memory. 54 */ 55#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS)) 56 57unsigned long ptv_memsize; 58 59/* 60 * struct low_mem_reserved - Items in low memory that are reserved 61 * @start: Physical address of item 62 * @size: Size, in bytes, of this item 63 * @is_aliased: True if this is RAM aliased from another location. If false, 64 * it is something other than aliased RAM and the RAM in the 65 * unaliased address is still visible outside of low memory. 66 */ 67struct low_mem_reserved { 68 phys_addr_t start; 69 phys_addr_t size; 70 bool is_aliased; 71}; 72 73/* 74 * Must be in ascending address order 75 */ 76struct low_mem_reserved low_mem_reserved[] = { 77 {BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */ 78 {RV_PHYS, RV_SIZE, false}, /* Reset vector */ 79}; 80 81/* 82 * struct mem_layout - layout of a piece of the system RAM 83 * @phys: Physical address of the start of this piece of RAM. This is the 84 * address at which both the processor and I/O devices see the 85 * RAM. 86 * @alias: Alias of this piece of memory in order to make it appear in 87 * the low memory part of the processor's address space. I/O 88 * devices don't see anything here. 89 * @size: Size, in bytes, of this piece of RAM 90 */ 91struct mem_layout { 92 phys_addr_t phys; 93 phys_addr_t alias; 94 phys_addr_t size; 95}; 96 97/* 98 * struct mem_layout_list - list descriptor for layouts of system RAM pieces 99 * @family: Specifies the family being described 100 * @n: Number of &struct mem_layout elements 101 * @layout: Pointer to the list of &mem_layout structures 102 */ 103struct mem_layout_list { 104 enum family_type family; 105 size_t n; 106 struct mem_layout *layout; 107}; 108 109static struct mem_layout f1500_layout[] = { 110 {0x20000000, 0x10000000, MEBIBYTE(256)}, 111}; 112 113static struct mem_layout f4500_layout[] = { 114 {0x40000000, 0x10000000, MEBIBYTE(256)}, 115 {0x20000000, 0x20000000, MEBIBYTE(32)}, 116}; 117 118static struct mem_layout f8500_layout[] = { 119 {0x40000000, 0x10000000, MEBIBYTE(256)}, 120 {0x20000000, 0x20000000, MEBIBYTE(32)}, 121 {0x30000000, 0x30000000, MEBIBYTE(32)}, 122}; 123 124static struct mem_layout fx600_layout[] = { 125 {0x20000000, 0x10000000, MEBIBYTE(256)}, 126 {0x60000000, 0x60000000, MEBIBYTE(128)}, 127}; 128 129static struct mem_layout_list layout_list[] = { 130 {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout}, 131 {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout}, 132 {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout}, 133 {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout}, 134 {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout}, 135 {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout}, 136 {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout}, 137 {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout}, 138 {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout}, 139 {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout}, 140}; 141 142/* If we can't determine the layout, use this */ 143static struct mem_layout default_layout[] = { 144 {0x20000000, 0x10000000, MEBIBYTE(128)}, 145}; 146 147/** 148 * register_non_ram - register low memory not available for RAM usage 149 */ 150static __init void register_non_ram(void) 151{ 152 int i; 153 154 for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++) 155 add_memory_region(low_mem_reserved[i].start, 156 low_mem_reserved[i].size, BOOT_MEM_RESERVED); 157} 158 159/** 160 * get_memsize - get the size of memory as a single bank 161 */ 162static phys_addr_t get_memsize(void) 163{ 164 static char cmdline[COMMAND_LINE_SIZE] __initdata; 165 phys_addr_t memsize = 0; 166 char *memsize_str; 167 char *ptr; 168 169 /* Check the command line first for a memsize directive */ 170 strcpy(cmdline, arcs_cmdline); 171 ptr = strstr(cmdline, "memsize="); 172 if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) 173 ptr = strstr(ptr, " memsize="); 174 175 if (ptr) { 176 memsize = memparse(ptr + 8, &ptr); 177 } else { 178 /* otherwise look in the environment */ 179 memsize_str = prom_getenv("memsize"); 180 181 if (memsize_str != NULL) { 182 pr_info("prom memsize = %s\n", memsize_str); 183 memsize = simple_strtol(memsize_str, NULL, 0); 184 } 185 186 if (memsize == 0) { 187 if (_prom_memsize != 0) { 188 memsize = _prom_memsize; 189 pr_info("_prom_memsize = 0x%x\n", memsize); 190 /* add in memory that the bootloader doesn't 191 * report */ 192 memsize += BLDR_SIZE; 193 } else { 194 memsize = DEFAULT_MEMSIZE; 195 pr_info("Memsize not passed by bootloader, " 196 "defaulting to 0x%x\n", memsize); 197 } 198 } 199 } 200 201 return memsize; 202} 203 204/** 205 * register_low_ram - register an aliased section of RAM 206 * @p: Alias address of memory 207 * @n: Number of bytes in this section of memory 208 * 209 * Returns the number of bytes registered 210 * 211 */ 212static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n) 213{ 214 phys_addr_t s; 215 int i; 216 phys_addr_t orig_n; 217 218 orig_n = n; 219 220 BUG_ON(p + n > RV_PHYS); 221 222 for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) { 223 phys_addr_t start; 224 phys_addr_t size; 225 226 start = low_mem_reserved[i].start; 227 size = low_mem_reserved[i].size; 228 229 /* Handle memory before this low memory section */ 230 if (p < start) { 231 phys_addr_t s; 232 s = min(n, start - p); 233 add_memory_region(p, s, BOOT_MEM_RAM); 234 p += s; 235 n -= s; 236 } 237 238 /* Handle the low memory section itself. If it's aliased, 239 * we reduce the number of byes left, but if not, the RAM 240 * is available elsewhere and we don't reduce the number of 241 * bytes remaining. */ 242 if (p == start) { 243 if (low_mem_reserved[i].is_aliased) { 244 s = min(n, size); 245 n -= s; 246 p += s; 247 } else 248 p += n; 249 } 250 } 251 252 return orig_n - n; 253} 254 255/* 256 * register_ram - register real RAM 257 * @p: Address of memory as seen by devices 258 * @alias: If the memory is seen at an additional address by the processor, 259 * this will be the address, otherwise it is the same as @p. 260 * @n: Number of bytes in this section of memory 261 */ 262static __init void register_ram(phys_addr_t p, phys_addr_t alias, 263 phys_addr_t n) 264{ 265 /* 266 * If some or all of this memory has an alias, break it into the 267 * aliased and non-aliased portion. 268 */ 269 if (p != alias) { 270 phys_addr_t alias_size; 271 phys_addr_t registered; 272 273 alias_size = min(n, LOW_RAM_END - alias); 274 registered = register_low_ram(alias, alias_size); 275 ioremap_add_map(alias, p, n); 276 n -= registered; 277 p += registered; 278 } 279 280#ifdef CONFIG_HIGHMEM 281 if (n != 0) { 282 add_memory_region(p, n, BOOT_MEM_RAM); 283 ioremap_add_map(p, p, n); 284 } 285#endif 286} 287 288/** 289 * register_address_space - register things in the address space 290 * @memsize: Number of bytes of RAM installed 291 * 292 * Takes the given number of bytes of RAM and registers as many of the regions, 293 * or partial regions, as it can. So, the default configuration might have 294 * two regions with 256 MiB each. If the memsize passed in on the command line 295 * is 384 MiB, it will register the first region with 256 MiB and the second 296 * with 128 MiB. 297 */ 298static __init void register_address_space(phys_addr_t memsize) 299{ 300 int i; 301 phys_addr_t size; 302 size_t n; 303 struct mem_layout *layout; 304 enum family_type family; 305 306 /* 307 * Register all of the things that aren't available to the kernel as 308 * memory. 309 */ 310 register_non_ram(); 311 312 /* Find the appropriate memory description */ 313 family = platform_get_family(); 314 315 for (i = 0; i < ARRAY_SIZE(layout_list); i++) { 316 if (layout_list[i].family == family) 317 break; 318 } 319 320 if (i == ARRAY_SIZE(layout_list)) { 321 n = ARRAY_SIZE(default_layout); 322 layout = default_layout; 323 } else { 324 n = layout_list[i].n; 325 layout = layout_list[i].layout; 326 } 327 328 for (i = 0; memsize != 0 && i < n; i++) { 329 size = min(memsize, layout[i].size); 330 register_ram(layout[i].phys, layout[i].alias, size); 331 memsize -= size; 332 } 333} 334 335void __init prom_meminit(void) 336{ 337 ptv_memsize = get_memsize(); 338 register_address_space(ptv_memsize); 339} 340 341void __init prom_free_prom_memory(void) 342{ 343 unsigned long addr; 344 int i; 345 346 for (i = 0; i < boot_mem_map.nr_map; i++) { 347 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) 348 continue; 349 350 addr = boot_mem_map.map[i].addr; 351 free_init_pages("prom memory", 352 addr, addr + boot_mem_map.map[i].size); 353 } 354} 355