Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sead3-memory.c
Go to the documentation of this file.
1 /*
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 
18 };
19 
21 
22 /* determined physical memory size, not overridden by command line args */
23 unsigned long physical_memsize = 0L;
24 
26 {
27  char *memsize_str, *ptr;
28  unsigned int memsize;
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 */
47 #endif
48 
49  /* Check the command line for a memsize directive that overrides
50  the physical/default amount */
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 
94 static 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 
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 
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 }