blob: da9244106f86f5a46ca4be296abca13ff0bc6e22 [file] [log] [blame]
Steven J. Hill30700332012-05-30 21:02:49 +00001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8#include <linux/bootmem.h>
9
10#include <asm/bootinfo.h>
11#include <asm/sections.h>
12#include <asm/mips-boards/prom.h>
13
14enum yamon_memtypes {
15 yamon_dontuse,
16 yamon_prom,
17 yamon_free,
18};
19
20static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
21
22/* determined physical memory size, not overridden by command line args */
23unsigned long physical_memsize = 0L;
24
25struct prom_pmemblock * __init prom_getmdesc(void)
26{
27 char *memsize_str, *ptr;
28 unsigned int memsize;
29 static char cmdline[COMMAND_LINE_SIZE] __initdata;
30 long val;
31 int tmp;
32
33 /* otherwise look in the environment */
34 memsize_str = prom_getenv("memsize");
35 if (!memsize_str) {
36 pr_warn("memsize not set in boot prom, set to default 32Mb\n");
37 physical_memsize = 0x02000000;
38 } else {
39 tmp = kstrtol(memsize_str, 0, &val);
40 physical_memsize = (unsigned long)val;
41 }
42
43#ifdef CONFIG_CPU_BIG_ENDIAN
44 /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
45 word of physical memory */
46 physical_memsize -= PAGE_SIZE;
47#endif
48
49 /* Check the command line for a memsize directive that overrides
50 the physical/default amount */
51 strcpy(cmdline, arcs_cmdline);
52 ptr = strstr(cmdline, "memsize=");
53 if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
54 ptr = strstr(ptr, " memsize=");
55
56 if (ptr)
57 memsize = memparse(ptr + 8, &ptr);
58 else
59 memsize = physical_memsize;
60
61 memset(mdesc, 0, sizeof(mdesc));
62
63 mdesc[0].type = yamon_dontuse;
64 mdesc[0].base = 0x00000000;
65 mdesc[0].size = 0x00001000;
66
67 mdesc[1].type = yamon_prom;
68 mdesc[1].base = 0x00001000;
69 mdesc[1].size = 0x000ef000;
70
71 /*
72 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
73 * south bridge and PCI access always forwarded to the ISA Bus and
74 * BIOSCS# is always generated.
75 * This mean that this area can't be used as DMA memory for PCI
76 * devices.
77 */
78 mdesc[2].type = yamon_dontuse;
79 mdesc[2].base = 0x000f0000;
80 mdesc[2].size = 0x00010000;
81
82 mdesc[3].type = yamon_dontuse;
83 mdesc[3].base = 0x00100000;
84 mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) -
85 mdesc[3].base;
86
87 mdesc[4].type = yamon_free;
88 mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
89 mdesc[4].size = memsize - mdesc[4].base;
90
91 return &mdesc[0];
92}
93
94static int __init prom_memtype_classify(unsigned int type)
95{
96 switch (type) {
97 case yamon_free:
98 return BOOT_MEM_RAM;
99 case yamon_prom:
100 return BOOT_MEM_ROM_DATA;
101 default:
102 return BOOT_MEM_RESERVED;
103 }
104}
105
106void __init prom_meminit(void)
107{
108 struct prom_pmemblock *p;
109
110 p = prom_getmdesc();
111
112 while (p->size) {
113 long type;
114 unsigned long base, size;
115
116 type = prom_memtype_classify(p->type);
117 base = p->base;
118 size = p->size;
119
120 add_memory_region(base, size, type);
121 p++;
122 }
123}
124
125void __init prom_free_prom_memory(void)
126{
127 unsigned long addr;
128 int i;
129
130 for (i = 0; i < boot_mem_map.nr_map; i++) {
131 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
132 continue;
133
134 addr = boot_mem_map.map[i].addr;
135 free_init_pages("prom memory",
136 addr, addr + boot_mem_map.map[i].size);
137 }
138}