Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
49bffbdc SH |
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. | |
1da177e4 LT |
5 | * |
6 | * PROM library functions for acquiring/using memory descriptors given to | |
7 | * us from the YAMON. | |
49bffbdc SH |
8 | * |
9 | * Copyright (C) 1999,2000,2012 MIPS Technologies, Inc. | |
10 | * All rights reserved. | |
11 | * Authors: Carsten Langgaard <carstenl@mips.com> | |
12 | * Steven J. Hill <sjhill@mips.com> | |
1da177e4 | 13 | */ |
1da177e4 | 14 | #include <linux/init.h> |
1da177e4 | 15 | #include <linux/bootmem.h> |
e01402b1 | 16 | #include <linux/string.h> |
1da177e4 LT |
17 | |
18 | #include <asm/bootinfo.h> | |
9c1f1257 | 19 | #include <asm/sections.h> |
b431f09d | 20 | #include <asm/fw/fw.h> |
1da177e4 | 21 | |
b431f09d | 22 | static fw_memblock_t mdesc[FW_MAX_MEMBLOCKS]; |
1da177e4 | 23 | |
70342287 | 24 | /* determined physical memory size, not overridden by command line args */ |
e1a4e469 RB |
25 | unsigned long physical_memsize = 0L; |
26 | ||
b431f09d | 27 | fw_memblock_t * __init fw_getmdesc(void) |
1da177e4 | 28 | { |
49bffbdc | 29 | char *memsize_str, *ptr; |
1da177e4 | 30 | unsigned int memsize; |
7580c9c3 | 31 | static char cmdline[COMMAND_LINE_SIZE] __initdata; |
49bffbdc SH |
32 | long val; |
33 | int tmp; | |
1da177e4 | 34 | |
e1a4e469 | 35 | /* otherwise look in the environment */ |
b431f09d | 36 | memsize_str = fw_getenv("memsize"); |
e1a4e469 | 37 | if (!memsize_str) { |
49bffbdc | 38 | pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); |
e1a4e469 RB |
39 | physical_memsize = 0x02000000; |
40 | } else { | |
49bffbdc SH |
41 | tmp = kstrtol(memsize_str, 0, &val); |
42 | physical_memsize = (unsigned long)val; | |
1da177e4 | 43 | } |
73499682 EO |
44 | |
45 | #ifdef CONFIG_CPU_BIG_ENDIAN | |
e1a4e469 RB |
46 | /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last |
47 | word of physical memory */ | |
48 | physical_memsize -= PAGE_SIZE; | |
73499682 EO |
49 | #endif |
50 | ||
e1a4e469 RB |
51 | /* Check the command line for a memsize directive that overrides |
52 | the physical/default amount */ | |
53 | strcpy(cmdline, arcs_cmdline); | |
54 | ptr = strstr(cmdline, "memsize="); | |
55 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
56 | ptr = strstr(ptr, " memsize="); | |
57 | ||
58 | if (ptr) | |
59 | memsize = memparse(ptr + 8, &ptr); | |
60 | else | |
61 | memsize = physical_memsize; | |
62 | ||
1da177e4 LT |
63 | memset(mdesc, 0, sizeof(mdesc)); |
64 | ||
b431f09d | 65 | mdesc[0].type = fw_dontuse; |
1da177e4 LT |
66 | mdesc[0].base = 0x00000000; |
67 | mdesc[0].size = 0x00001000; | |
68 | ||
b431f09d | 69 | mdesc[1].type = fw_code; |
1da177e4 LT |
70 | mdesc[1].base = 0x00001000; |
71 | mdesc[1].size = 0x000ef000; | |
72 | ||
1da177e4 LT |
73 | /* |
74 | * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | |
75 | * south bridge and PCI access always forwarded to the ISA Bus and | |
76 | * BIOSCS# is always generated. | |
77 | * This mean that this area can't be used as DMA memory for PCI | |
78 | * devices. | |
79 | */ | |
b431f09d | 80 | mdesc[2].type = fw_dontuse; |
1da177e4 LT |
81 | mdesc[2].base = 0x000f0000; |
82 | mdesc[2].size = 0x00010000; | |
1da177e4 | 83 | |
b431f09d | 84 | mdesc[3].type = fw_dontuse; |
1da177e4 | 85 | mdesc[3].base = 0x00100000; |
49bffbdc SH |
86 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - |
87 | mdesc[3].base; | |
1da177e4 | 88 | |
b431f09d | 89 | mdesc[4].type = fw_free; |
fde3505c | 90 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
1da177e4 LT |
91 | mdesc[4].size = memsize - mdesc[4].base; |
92 | ||
93 | return &mdesc[0]; | |
94 | } | |
95 | ||
b431f09d | 96 | static int __init fw_memtype_classify(unsigned int type) |
1da177e4 LT |
97 | { |
98 | switch (type) { | |
b431f09d | 99 | case fw_free: |
1da177e4 | 100 | return BOOT_MEM_RAM; |
b431f09d | 101 | case fw_code: |
1da177e4 LT |
102 | return BOOT_MEM_ROM_DATA; |
103 | default: | |
104 | return BOOT_MEM_RESERVED; | |
105 | } | |
106 | } | |
107 | ||
b431f09d | 108 | void __init fw_meminit(void) |
1da177e4 | 109 | { |
b431f09d | 110 | fw_memblock_t *p; |
1da177e4 | 111 | |
b431f09d | 112 | p = fw_getmdesc(); |
1da177e4 LT |
113 | |
114 | while (p->size) { | |
115 | long type; | |
116 | unsigned long base, size; | |
117 | ||
b431f09d | 118 | type = fw_memtype_classify(p->type); |
1da177e4 LT |
119 | base = p->base; |
120 | size = p->size; | |
121 | ||
122 | add_memory_region(base, size, type); | |
70342287 | 123 | p++; |
1da177e4 LT |
124 | } |
125 | } | |
126 | ||
c44e8d5e | 127 | void __init prom_free_prom_memory(void) |
1da177e4 | 128 | { |
1da177e4 LT |
129 | unsigned long addr; |
130 | int i; | |
131 | ||
132 | for (i = 0; i < boot_mem_map.nr_map; i++) { | |
133 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
134 | continue; | |
135 | ||
c44e8d5e | 136 | addr = boot_mem_map.map[i].addr; |
49bffbdc | 137 | free_init_pages("YAMON memory", |
c44e8d5e | 138 | addr, addr + boot_mem_map.map[i].size); |
1da177e4 | 139 | } |
1da177e4 | 140 | } |