aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/setup.c
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2013-08-06 14:29:59 -0400
committerChris Metcalf <cmetcalf@tilera.com>2013-08-12 14:46:43 -0400
commit77f8c740d1a4947afb7493e7aafdd977e6d7939c (patch)
tree67470387bec62f1a5475d194f4b6175dda079eb9 /arch/tile/kernel/setup.c
parentbda0f5bad812df076a28fa5e58d86dfe68415251 (diff)
tile: support "memmap" boot parameter
This change adds support for the "memmap" boot parameter similar to what x86 provides. The tile version supports "memmap=1G$5G", for example, as a way to reserve a 1 GB range starting at PA 5GB. The memory is reserved via bootmem during startup, and we create a suitable "struct resource" marked as "Reserved" so you can see the range reported by /proc/iomem. Up to 64 such regions can currently be reserved on the boot command line. We do not support the x86 options "memmap=nn@ss" (force some memory to be available at the given address) since it's pointless to try to have Linux use memory the Tilera hypervisor hasn't given it. We do not support "memmap=nn#ss" to add an ACPI range for later processing, since we don't support ACPI. We do not support "memmap=exactmap" since we don't support reading the e820 information from the BIOS like x86 does. I did add support for "memmap=nn" (and the synonym "mem=nn") which cap the highest PA value at "nn"; these are both just a synonym for the existing tile boot option "maxmem". Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/setup.c')
-rw-r--r--arch/tile/kernel/setup.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index 676e155a0d63..b00e156118c3 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -154,6 +154,65 @@ static int __init setup_maxnodemem(char *str)
154} 154}
155early_param("maxnodemem", setup_maxnodemem); 155early_param("maxnodemem", setup_maxnodemem);
156 156
157struct memmap_entry {
158 u64 addr; /* start of memory segment */
159 u64 size; /* size of memory segment */
160};
161static struct memmap_entry memmap_map[64];
162static int memmap_nr;
163
164static void add_memmap_region(u64 addr, u64 size)
165{
166 if (memmap_nr >= ARRAY_SIZE(memmap_map)) {
167 pr_err("Ooops! Too many entries in the memory map!\n");
168 return;
169 }
170 memmap_map[memmap_nr].addr = addr;
171 memmap_map[memmap_nr].size = size;
172 memmap_nr++;
173}
174
175static int __init setup_memmap(char *p)
176{
177 char *oldp;
178 u64 start_at, mem_size;
179
180 if (!p)
181 return -EINVAL;
182
183 if (!strncmp(p, "exactmap", 8)) {
184 pr_err("\"memmap=exactmap\" not valid on tile\n");
185 return 0;
186 }
187
188 oldp = p;
189 mem_size = memparse(p, &p);
190 if (p == oldp)
191 return -EINVAL;
192
193 if (*p == '@') {
194 pr_err("\"memmap=nn@ss\" (force RAM) invalid on tile\n");
195 } else if (*p == '#') {
196 pr_err("\"memmap=nn#ss\" (force ACPI data) invalid on tile\n");
197 } else if (*p == '$') {
198 start_at = memparse(p+1, &p);
199 add_memmap_region(start_at, mem_size);
200 } else {
201 if (mem_size == 0)
202 return -EINVAL;
203 maxmem_pfn = (mem_size >> HPAGE_SHIFT) <<
204 (HPAGE_SHIFT - PAGE_SHIFT);
205 }
206 return *p == '\0' ? 0 : -EINVAL;
207}
208early_param("memmap", setup_memmap);
209
210static int __init setup_mem(char *str)
211{
212 return setup_maxmem(str);
213}
214early_param("mem", setup_mem); /* compatibility with x86 */
215
157static int __init setup_isolnodes(char *str) 216static int __init setup_isolnodes(char *str)
158{ 217{
159 char buf[MAX_NUMNODES * 5]; 218 char buf[MAX_NUMNODES * 5];
@@ -629,6 +688,12 @@ static void __init setup_bootmem_allocator(void)
629 for (i = 0; i < MAX_NUMNODES; ++i) 688 for (i = 0; i < MAX_NUMNODES; ++i)
630 setup_bootmem_allocator_node(i); 689 setup_bootmem_allocator_node(i);
631 690
691 /* Reserve any memory excluded by "memmap" arguments. */
692 for (i = 0; i < memmap_nr; ++i) {
693 struct memmap_entry *m = &memmap_map[i];
694 reserve_bootmem(m->addr, m->size, 0);
695 }
696
632#ifdef CONFIG_KEXEC 697#ifdef CONFIG_KEXEC
633 if (crashk_res.start != crashk_res.end) 698 if (crashk_res.start != crashk_res.end)
634 reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0); 699 reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0);
@@ -1562,11 +1627,11 @@ insert_non_bus_resource(void)
1562#endif 1627#endif
1563 1628
1564static struct resource* __init 1629static struct resource* __init
1565insert_ram_resource(u64 start_pfn, u64 end_pfn) 1630insert_ram_resource(u64 start_pfn, u64 end_pfn, bool reserved)
1566{ 1631{
1567 struct resource *res = 1632 struct resource *res =
1568 kzalloc(sizeof(struct resource), GFP_ATOMIC); 1633 kzalloc(sizeof(struct resource), GFP_ATOMIC);
1569 res->name = "System RAM"; 1634 res->name = reserved ? "Reserved" : "System RAM";
1570 res->start = start_pfn << PAGE_SHIFT; 1635 res->start = start_pfn << PAGE_SHIFT;
1571 res->end = (end_pfn << PAGE_SHIFT) - 1; 1636 res->end = (end_pfn << PAGE_SHIFT) - 1;
1572 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; 1637 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
@@ -1601,11 +1666,11 @@ static int __init request_standard_resources(void)
1601 end_pfn > pci_reserve_start_pfn) { 1666 end_pfn > pci_reserve_start_pfn) {
1602 if (end_pfn > pci_reserve_end_pfn) 1667 if (end_pfn > pci_reserve_end_pfn)
1603 insert_ram_resource(pci_reserve_end_pfn, 1668 insert_ram_resource(pci_reserve_end_pfn,
1604 end_pfn); 1669 end_pfn, 0);
1605 end_pfn = pci_reserve_start_pfn; 1670 end_pfn = pci_reserve_start_pfn;
1606 } 1671 }
1607#endif 1672#endif
1608 insert_ram_resource(start_pfn, end_pfn); 1673 insert_ram_resource(start_pfn, end_pfn, 0);
1609 } 1674 }
1610 1675
1611 code_resource.start = __pa(_text - CODE_DELTA); 1676 code_resource.start = __pa(_text - CODE_DELTA);
@@ -1616,6 +1681,13 @@ static int __init request_standard_resources(void)
1616 insert_resource(&iomem_resource, &code_resource); 1681 insert_resource(&iomem_resource, &code_resource);
1617 insert_resource(&iomem_resource, &data_resource); 1682 insert_resource(&iomem_resource, &data_resource);
1618 1683
1684 /* Mark any "memmap" regions busy for the resource manager. */
1685 for (i = 0; i < memmap_nr; ++i) {
1686 struct memmap_entry *m = &memmap_map[i];
1687 insert_ram_resource(PFN_DOWN(m->addr),
1688 PFN_UP(m->addr + m->size - 1), 1);
1689 }
1690
1619#ifdef CONFIG_KEXEC 1691#ifdef CONFIG_KEXEC
1620 insert_resource(&iomem_resource, &crashk_res); 1692 insert_resource(&iomem_resource, &crashk_res);
1621#endif 1693#endif