From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:20:52 +0000
Subject: [PATCH] add new system file
---
kernel/arch/mips/fw/arc/memory.c | 67 ++++++++++++++++++++++++---------
1 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/kernel/arch/mips/fw/arc/memory.c b/kernel/arch/mips/fw/arc/memory.c
index dd9496f..37625ae 100644
--- a/kernel/arch/mips/fw/arc/memory.c
+++ b/kernel/arch/mips/fw/arc/memory.c
@@ -17,15 +17,19 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/swap.h>
#include <asm/sgialib.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/bootinfo.h>
#undef DEBUG
+
+#define MAX_PROM_MEM 5
+static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
+static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
+static unsigned int nr_prom_mem __initdata;
/*
* For ARC firmware memory functions the unit of meassuring memory is always
@@ -64,20 +68,24 @@
: arc_mtypes[a.arc]
#endif
+enum {
+ mem_free, mem_prom_used, mem_reserved
+};
+
static inline int memtype_classify_arcs(union linux_memtypes type)
{
switch (type.arcs) {
case arcs_fcontig:
case arcs_free:
- return BOOT_MEM_RAM;
+ return mem_free;
case arcs_atmp:
- return BOOT_MEM_ROM_DATA;
+ return mem_prom_used;
case arcs_eblock:
case arcs_rvpage:
case arcs_bmem:
case arcs_prog:
case arcs_aperm:
- return BOOT_MEM_RESERVED;
+ return mem_reserved;
default:
BUG();
}
@@ -89,15 +97,15 @@
switch (type.arc) {
case arc_free:
case arc_fcontig:
- return BOOT_MEM_RAM;
+ return mem_free;
case arc_atmp:
- return BOOT_MEM_ROM_DATA;
+ return mem_prom_used;
case arc_eblock:
case arc_rvpage:
case arc_bmem:
case arc_prog:
case arc_aperm:
- return BOOT_MEM_RESERVED;
+ return mem_reserved;
default:
BUG();
}
@@ -112,7 +120,7 @@
return memtype_classify_arc(type);
}
-void __init prom_meminit(void)
+void __weak __init prom_meminit(void)
{
struct linux_mdesc *p;
@@ -129,6 +137,7 @@
}
#endif
+ nr_prom_mem = 0;
p = PROM_NULL_MDESC;
while ((p = ArcGetMemoryDescriptor(p))) {
unsigned long base, size;
@@ -138,24 +147,46 @@
size = p->pages << ARC_PAGE_SHIFT;
type = prom_memtype_classify(p->type);
- add_memory_region(base, size, type);
+ /* ignore mirrored RAM on IP28/IP30 */
+ if (base < PHYS_OFFSET)
+ continue;
+
+ memblock_add(base, size);
+
+ if (type == mem_reserved)
+ memblock_reserve(base, size);
+
+ if (type == mem_prom_used) {
+ memblock_reserve(base, size);
+ if (nr_prom_mem >= 5) {
+ pr_err("Too many ROM DATA regions");
+ continue;
+ }
+ prom_mem_base[nr_prom_mem] = base;
+ prom_mem_size[nr_prom_mem] = size;
+ nr_prom_mem++;
+ }
}
}
-void __init prom_free_prom_memory(void)
+void __weak __init prom_cleanup(void)
{
- unsigned long addr;
+}
+
+void __weak __init prom_free_prom_memory(void)
+{
int i;
if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
return;
- for (i = 0; i < boot_mem_map.nr_map; i++) {
- if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
- continue;
-
- addr = boot_mem_map.map[i].addr;
+ for (i = 0; i < nr_prom_mem; i++) {
free_init_pages("prom memory",
- addr, addr + boot_mem_map.map[i].size);
+ prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
}
+ /*
+ * at this point it isn't safe to call PROM functions
+ * give platforms a way to do PROM cleanups
+ */
+ prom_cleanup();
}
--
Gitblit v1.6.2