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.
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.
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
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.
19 * Apparently originally from arch/mips/malta-memory.c. Modified to work
20 * with the PowerTV bootloader.
22 #include <linux/init.h>
24 #include <linux/bootmem.h>
25 #include <linux/pfn.h>
26 #include <linux/string.h>
28 #include <asm/bootinfo.h>
30 #include <asm/sections.h>
32 #include <asm/mips-boards/prom.h>
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 */
45 unsigned long ptv_memsize;
47 char __initdata cmdline[COMMAND_LINE_SIZE];
49 void __init prom_meminit(void)
52 unsigned long memsize = 0;
58 /* Check the command line first for a memsize directive */
59 strcpy(cmdline, arcs_cmdline);
60 ptr = strstr(cmdline, "memsize=");
61 if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
62 ptr = strstr(ptr, " memsize=");
65 memsize = memparse(ptr + 8, &ptr);
67 /* otherwise look in the environment */
68 memsize_str = prom_getenv("memsize");
70 if (memsize_str != NULL) {
71 pr_info("prom memsize = %s\n", memsize_str);
72 memsize = simple_strtol(memsize_str, NULL, 0);
76 if (_prom_memsize != 0) {
77 memsize = _prom_memsize;
78 pr_info("_prom_memsize = 0x%lx\n", memsize);
79 /* add in memory that the bootloader doesn't
81 memsize += BOOT_MEM_SIZE;
83 memsize = DEFAULT_MEMSIZE;
84 pr_info("Memsize not passed by bootloader, "
85 "defaulting to 0x%lx\n", memsize);
90 /* Store memsize for diagnostic purposes */
91 ptv_memsize = memsize;
93 physend = PFN_ALIGN(&_end) - 0x80000000;
94 if (memsize > LOW_MEM_MAX) {
95 low_mem = LOW_MEM_MAX;
96 high_mem = memsize - low_mem;
103 * TODO: We will use the hard code for memory configuration until
104 * the bootloader releases their device tree to us.
107 * Add the memory reserved for use by the bootloader to the
110 add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
112 #ifdef CONFIG_HIGHMEM_256_128
114 * Add memory in low for general use by the kernel and its friends
115 * (like drivers, applications, etc).
117 add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
118 LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
120 * Add the memory reserved for reset vector.
122 add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
124 * Add the memory reserved.
126 add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
128 * Add memory in high for general use by the kernel and its friends
129 * (like drivers, applications, etc).
131 * 75MB is reserved for devices which are using the memory in high.
133 add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
135 #elif defined CONFIG_HIGHMEM_128_128
137 * Add memory in low for general use by the kernel and its friends
138 * (like drivers, applications, etc).
140 add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
141 MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
143 * Add the memory reserved.
145 add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
146 MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
148 * Add memory in high for general use by the kernel and its friends
149 * (like drivers, applications, etc).
151 * 75MB is reserved for devices which are using the memory in high.
153 add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
156 /* Add low memory regions for either:
157 * - no-highmemory configuration case -OR-
158 * - highmemory "HIGHMEM_LOWBANK_ONLY" case
161 * Add memory for general use by the kernel and its friends
162 * (like drivers, applications, etc).
164 add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
165 low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
167 * Add the memory reserved for reset vector.
169 add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
173 void __init prom_free_prom_memory(void)
178 for (i = 0; i < boot_mem_map.nr_map; i++) {
179 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
182 addr = boot_mem_map.map[i].addr;
183 free_init_pages("prom memory",
184 addr, addr + boot_mem_map.map[i].size);