* [PATCH 0/5] sparc32: replace sp_banks with memblock
@ 2026-08-27 18:24 Magnus Lindholm
2026-08-27 18:24 ` [PATCH 1/5] sparc32: use memblock when mapping the kernel Magnus Lindholm
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
Replace the sparc32-private sp_banks memory description with memblock.
The first two patches convert the SRMMU consumers that already run after
bootmem_init() has populated memblock. The third patch moves memblock
population to prom_meminit() and applies the mem= limit there, keeping that
intermediate state correct. The fourth patch moves the early memory setup
into setup_32.c and the final patch removes the now-unused sp_banks array.
This work is based on an earlier eight-patch series by Sam Ravnborg.
Patch 2 directly carries over Sam's memblock sizing conversion. The series
has otherwise been substantially reorganized and reworked for the current
kernel. Compared with Sam's series, this version is ported to the current
generic MM setup, keeps the sparc32 mem= command-line option by using
memblock_enforce_memory_limit(), and uses memblock's exclusive range-end
semantics throughout.
The series is based on top of the sparc32 phys_base and Viking fixes. In
particular, setup_memory() preserves the relocated-kernel handling by
removing RAM below the physical address to which PAGE_OFFSET maps.
This series is boot tested on a Sun SPARCstation-20 with dual
Supersparc-II cpu (SM71) as well as dual Hypersparc RT626.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://lore.kernel.org/r/20260817153237.GA702187@ravnborg.org
Magnus Lindholm (5):
sparc32: use memblock when mapping the kernel
sparc32: use memblock to find available system memory
sparc32: populate memblock from the PROM memory map
sparc32: move early memory setup to setup_arch
sparc32: drop sp_banks
arch/sparc/include/asm/page_32.h | 16 ----
arch/sparc/include/asm/pgtable_32.h | 3 +-
arch/sparc/kernel/setup_32.c | 118 +++++++++++++----------
arch/sparc/mm/init_32.c | 139 +---------------------------
arch/sparc/mm/srmmu.c | 65 +++++--------
arch/sparc/prom/memory.c | 51 ++--------
6 files changed, 104 insertions(+), 288 deletions(-)
base-commit: 982260b3f81e405af4a65a3029399840a2d2a4be
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] sparc32: use memblock when mapping the kernel
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
@ 2026-08-27 18:24 ` Magnus Lindholm
2026-08-27 18:24 ` [PATCH 2/5] sparc32: use memblock to find available system memory Magnus Lindholm
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
memblock already contains the available memory ranges when map_kernel()
runs. Iterate those ranges directly and remove the sp_banks-specific
mapping helper. memblock range ends are exclusive, so use end - start as
the range size.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/sparc/mm/srmmu.c | 47 +++++++++++++++++++------------------------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index f0fe09169528..483235458d69 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -846,39 +846,34 @@ static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base
*__nocache_fix(pgdp) = __pgd(big_pte);
}
-/* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE. */
-static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
-{
- unsigned long pstart = (sp_banks[sp_entry].base_addr & PGDIR_MASK);
- unsigned long vstart = (vbase & PGDIR_MASK);
- unsigned long vend = PGDIR_ALIGN(vbase + sp_banks[sp_entry].num_bytes);
- /* Map "low" memory only */
- const unsigned long min_vaddr = PAGE_OFFSET;
- const unsigned long max_vaddr = PAGE_OFFSET + SRMMU_MAXMEM;
-
- if (vstart < min_vaddr || vstart >= max_vaddr)
- return vstart;
-
- if (vend > max_vaddr || vend < min_vaddr)
- vend = max_vaddr;
-
- while (vstart < vend) {
- do_large_mapping(vstart, pstart);
- vstart += PGDIR_SIZE; pstart += PGDIR_SIZE;
- }
- return vstart;
-}
-
static void __init map_kernel(void)
{
- int i;
+ phys_addr_t start, end;
+ u64 i;
if (phys_base > 0) {
do_large_mapping(PAGE_OFFSET, phys_base);
}
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- map_spbank((unsigned long)__va(sp_banks[i].base_addr), i);
+ for_each_mem_range(i, &start, &end) {
+ unsigned long vbase = (unsigned long)__va(start);
+ unsigned long pstart = start & PGDIR_MASK;
+ unsigned long vstart = vbase & PGDIR_MASK;
+ unsigned long vend = PGDIR_ALIGN(vbase + end - start);
+ const unsigned long min_vaddr = PAGE_OFFSET;
+ const unsigned long max_vaddr = PAGE_OFFSET + SRMMU_MAXMEM;
+
+ /* Map low memory only. */
+ if (vstart < min_vaddr || vstart >= max_vaddr)
+ continue;
+ if (vend > max_vaddr || vend < min_vaddr)
+ vend = max_vaddr;
+
+ while (vstart < vend) {
+ do_large_mapping(vstart, pstart);
+ vstart += PGDIR_SIZE;
+ pstart += PGDIR_SIZE;
+ }
}
}
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/5] sparc32: use memblock to find available system memory
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
2026-08-27 18:24 ` [PATCH 1/5] sparc32: use memblock when mapping the kernel Magnus Lindholm
@ 2026-08-27 18:24 ` Magnus Lindholm
2026-08-27 18:24 ` [PATCH 3/5] sparc32: populate memblock from the PROM memory map Magnus Lindholm
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
The SRMMU nocache pool is sized after memblock has been populated. Use
memblock_phys_mem_size() instead of summing the private sp_banks array.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/sparc/mm/srmmu.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 483235458d69..3029527a5a9f 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -226,25 +226,13 @@ void srmmu_free_nocache(void *addr, int size)
static void srmmu_early_allocate_ptable_skeleton(unsigned long start,
unsigned long end);
-/* Return how much physical memory we have. */
-static unsigned long __init probe_memory(void)
-{
- unsigned long total = 0;
- int i;
-
- for (i = 0; sp_banks[i].num_bytes; i++)
- total += sp_banks[i].num_bytes;
-
- return total;
-}
-
/*
* Reserve nocache dynamically proportionally to the amount of
* system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002
*/
static void __init srmmu_nocache_calcsize(void)
{
- unsigned long sysmemavail = probe_memory() / 1024;
+ unsigned long sysmemavail = memblock_phys_mem_size() / 1024;
int srmmu_nocache_npages;
srmmu_nocache_npages =
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] sparc32: populate memblock from the PROM memory map
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
2026-08-27 18:24 ` [PATCH 1/5] sparc32: use memblock when mapping the kernel Magnus Lindholm
2026-08-27 18:24 ` [PATCH 2/5] sparc32: use memblock to find available system memory Magnus Lindholm
@ 2026-08-27 18:24 ` Magnus Lindholm
2026-08-27 18:24 ` [PATCH 4/5] sparc32: move early memory setup to setup_arch Magnus Lindholm
2026-08-27 18:24 ` [PATCH 5/5] sparc32: drop sp_banks Magnus Lindholm
4 siblings, 0 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
Add each available PROM memory range to memblock as it is discovered.
Keep populating sp_banks temporarily so the remaining users continue to
work while they are converted in the following patches.
Since the complete PROM map is now present before bootmem_init(), enforce
the mem= limit after the legacy bank processing. Adding a smaller
overlapping range would otherwise leave memory beyond the requested limit
in memblock during this intermediate commit.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/sparc/mm/init_32.c | 3 +++
arch/sparc/prom/memory.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index e0e66f91ceeb..75050dfbc2ea 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -165,6 +165,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
memblock_add(sp_banks[i].base_addr, sp_banks[i].num_bytes);
}
+ if (cmdline_memory_size)
+ memblock_enforce_memory_limit(cmdline_memory_size);
+
/* Start with page aligned address of last symbol in kernel
* image.
*/
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index 269d6ab5ef5e..59962bc0bc82 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
+#include <linux/memblock.h>
#include <linux/sort.h>
#include <linux/init.h>
@@ -23,6 +24,7 @@ static int __init prom_meminit_v0(void)
for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) {
sp_banks[index].base_addr = (unsigned long) p->start_adr;
sp_banks[index].num_bytes = p->num_bytes;
+ memblock_add(p->start_adr, p->num_bytes & PAGE_MASK);
index++;
}
@@ -42,6 +44,7 @@ static int __init prom_meminit_v2(void)
for (i = 0; i < num_ents; i++) {
sp_banks[i].base_addr = reg[i].phys_addr;
sp_banks[i].num_bytes = reg[i].reg_size;
+ memblock_add(reg[i].phys_addr, reg[i].reg_size & PAGE_MASK);
}
return num_ents;
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] sparc32: move early memory setup to setup_arch
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
` (2 preceding siblings ...)
2026-08-27 18:24 ` [PATCH 3/5] sparc32: populate memblock from the PROM memory map Magnus Lindholm
@ 2026-08-27 18:24 ` Magnus Lindholm
2026-08-27 18:24 ` [PATCH 5/5] sparc32: drop sp_banks Magnus Lindholm
4 siblings, 0 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
Move the early memory configuration out of SRMMU paging setup and next to
the rest of setup_arch(). Derive the PFN limits from memblock, reserve the
kernel and initrd there, and retain mem= support with
memblock_enforce_memory_limit().
When PAGE_OFFSET maps a relocated kernel, remove memory below phys_base
from memblock because it cannot be reached through the linear map. This
replaces the equivalent trimming of sp_banks.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/sparc/include/asm/pgtable_32.h | 3 +-
arch/sparc/kernel/setup_32.c | 118 +++++++++++++----------
arch/sparc/mm/init_32.c | 140 +---------------------------
arch/sparc/mm/srmmu.c | 4 -
4 files changed, 73 insertions(+), 192 deletions(-)
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index f89b1250661d..91a6032cf6a2 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -37,8 +37,7 @@ struct vm_area_struct;
struct page;
void load_mmu(void);
-unsigned long calc_highpages(void);
-unsigned long __init bootmem_init(unsigned long *pages_avail);
+void __init find_ramdisk(unsigned long end_of_phys_memory);
#define pte_ERROR(e) __builtin_trap()
#define pmd_ERROR(e) __builtin_trap()
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 795714959da6..e5f1c3ee36df 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -23,6 +23,7 @@
#include <linux/syscalls.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
+#include <linux/memblock.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -254,28 +255,77 @@ static __init void leon_patch(void)
struct tt_entry *sparc_ttable;
-/* Drop RAM below the kernel; the linear map runs upward from phys_base
- * and cannot reach it.
- */
-static void __init trim_sp_banks_below(unsigned long base)
+unsigned long phys_base;
+EXPORT_SYMBOL(phys_base);
+
+unsigned long pfn_base;
+EXPORT_SYMBOL(pfn_base);
+
+unsigned long highend_pfn;
+
+static unsigned long __init calc_max_low_pfn(void)
{
- int i, j = 0;
+ unsigned long limit = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
+ unsigned long last_pfn = 0;
+ phys_addr_t start, end;
+ u64 i;
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long start = sp_banks[i].base_addr;
- unsigned long end = start + sp_banks[i].num_bytes;
+ for_each_mem_range(i, &start, &end) {
+ unsigned long start_pfn = PFN_DOWN(start);
- if (end <= base)
- continue; /* wholly below - drop it */
- if (start < base)
- start = base; /* straddles - trim the front */
+ if (start_pfn >= limit) {
+ if (last_pfn < limit)
+ limit = last_pfn;
+ break;
+ }
- sp_banks[j].base_addr = start;
- sp_banks[j].num_bytes = end - start;
- j++;
+ last_pfn = PFN_DOWN(end);
}
- sp_banks[j].base_addr = 0;
- sp_banks[j].num_bytes = 0;
+
+ return limit;
+}
+
+static void __init setup_memory(void)
+{
+ unsigned long ram_base = memblock_start_of_DRAM();
+ unsigned long real_base = __get_phys(PAGE_OFFSET);
+ unsigned long size;
+
+ memblock_set_bottom_up(true);
+ memblock_allow_resize();
+
+ phys_base = ram_base;
+ if (real_base && real_base != phys_base) {
+ prom_printf("phys_base: RAM starts 0x%x but kernel is at 0x%x\n",
+ (unsigned int)phys_base, (unsigned int)real_base);
+ phys_base = real_base;
+ memblock_remove(0, phys_base);
+ prom_printf("phys_base: adopted 0x%x, RAM below it dropped\n",
+ (unsigned int)phys_base);
+ }
+
+ if (cmdline_memory_size)
+ memblock_enforce_memory_limit(cmdline_memory_size);
+
+ min_low_pfn = PFN_DOWN(memblock_start_of_DRAM());
+ pfn_base = phys_base >> PAGE_SHIFT;
+ max_pfn = PFN_DOWN(memblock_end_of_DRAM());
+ last_valid_pfn = max_pfn;
+ max_low_pfn = max_pfn;
+ highend_pfn = max_pfn;
+
+ if (max_low_pfn > pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT))
+ max_low_pfn = calc_max_low_pfn();
+
+ find_ramdisk(memblock_end_of_DRAM());
+
+ /* Reserve the kernel text/data/bss. */
+ size = __pa(PAGE_ALIGN((unsigned long)&_end)) - phys_base;
+ memblock_reserve(phys_base, size);
+ memblock_add(phys_base, size);
+
+ /* Only allow low memory to be allocated by memblock. */
+ memblock_set_current_limit(PFN_PHYS(max_low_pfn));
}
/* Called from head_32.S - before we have setup anything
@@ -306,9 +356,6 @@ void __init sparc32_start_kernel(struct linux_romvec *rp)
void __init setup_arch(char **cmdline_p)
{
- int i;
- unsigned long highest_paddr;
-
sparc_ttable = &trapbase[0];
/* Initialize PROM console and command line. */
@@ -343,36 +390,7 @@ void __init setup_arch(char **cmdline_p)
idprom_init();
load_mmu();
-
- phys_base = 0xffffffffUL;
- highest_paddr = 0UL;
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long top;
-
- if (sp_banks[i].base_addr < phys_base)
- phys_base = sp_banks[i].base_addr;
- top = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- if (highest_paddr < top)
- highest_paddr = top;
- }
-
- /* phys_base must describe what PAGE_OFFSET maps to, not where RAM starts. */
- {
- unsigned long real_base = __get_phys(PAGE_OFFSET);
-
- if (real_base && real_base != phys_base) {
- prom_printf("phys_base: RAM starts 0x%x but kernel is at 0x%x\n",
- (unsigned int)phys_base,
- (unsigned int)real_base);
- phys_base = real_base;
- trim_sp_banks_below(phys_base);
- prom_printf("phys_base: adopted 0x%x, RAM below it dropped\n",
- (unsigned int)phys_base);
- }
- }
-
- pfn_base = phys_base >> PAGE_SHIFT;
+ setup_memory();
if (!root_flags)
root_mountflags &= ~MS_RDONLY;
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 75050dfbc2ea..62c41d896421 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -39,66 +39,15 @@
static unsigned long *sparc_valid_addr_bitmap;
-unsigned long phys_base;
-EXPORT_SYMBOL(phys_base);
-
-unsigned long pfn_base;
-EXPORT_SYMBOL(pfn_base);
-
struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
/* Initial ramdisk setup */
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
-unsigned long highstart_pfn, highend_pfn;
-
unsigned long last_valid_pfn;
-unsigned long calc_highpages(void)
-{
- int i;
- int nr = 0;
-
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
- unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
-
- if (end_pfn <= max_low_pfn)
- continue;
-
- if (start_pfn < max_low_pfn)
- start_pfn = max_low_pfn;
-
- nr += end_pfn - start_pfn;
- }
-
- return nr;
-}
-
-static unsigned long calc_max_low_pfn(void)
-{
- int i;
- unsigned long tmp = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
- unsigned long curr_pfn, last_pfn;
-
- last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
- for (i = 1; sp_banks[i].num_bytes != 0; i++) {
- curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
-
- if (curr_pfn >= tmp) {
- if (last_pfn < tmp)
- tmp = last_pfn;
- break;
- }
-
- last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
- }
-
- return tmp;
-}
-
-static void __init find_ramdisk(unsigned long end_of_phys_memory)
+void __init find_ramdisk(unsigned long end_of_phys_memory)
{
#ifdef CONFIG_BLK_DEV_INITRD
unsigned long size;
@@ -128,83 +77,6 @@ static void __init find_ramdisk(unsigned long end_of_phys_memory)
#endif
}
-unsigned long __init bootmem_init(unsigned long *pages_avail)
-{
- unsigned long start_pfn, bytes_avail, size;
- unsigned long end_of_phys_memory = 0;
- unsigned long high_pages = 0;
- int i;
-
- memblock_set_bottom_up(true);
- memblock_allow_resize();
-
- bytes_avail = 0UL;
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- end_of_phys_memory = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- bytes_avail += sp_banks[i].num_bytes;
- if (cmdline_memory_size) {
- if (bytes_avail > cmdline_memory_size) {
- unsigned long slack = bytes_avail - cmdline_memory_size;
-
- bytes_avail -= slack;
- end_of_phys_memory -= slack;
-
- sp_banks[i].num_bytes -= slack;
- if (sp_banks[i].num_bytes == 0) {
- sp_banks[i].base_addr = 0xdeadbeef;
- } else {
- memblock_add(sp_banks[i].base_addr,
- sp_banks[i].num_bytes);
- sp_banks[i+1].num_bytes = 0;
- sp_banks[i+1].base_addr = 0xdeadbeef;
- }
- break;
- }
- }
- memblock_add(sp_banks[i].base_addr, sp_banks[i].num_bytes);
- }
-
- if (cmdline_memory_size)
- memblock_enforce_memory_limit(cmdline_memory_size);
-
- /* Start with page aligned address of last symbol in kernel
- * image.
- */
- start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
-
- /* Now shift down to get the real physical page frame number. */
- start_pfn >>= PAGE_SHIFT;
-
- max_pfn = end_of_phys_memory >> PAGE_SHIFT;
-
- max_low_pfn = max_pfn;
- highstart_pfn = highend_pfn = max_pfn;
-
- if (max_low_pfn > pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT)) {
- highstart_pfn = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
- max_low_pfn = calc_max_low_pfn();
- high_pages = calc_highpages();
- printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
- high_pages >> (20 - PAGE_SHIFT));
- }
-
- find_ramdisk(end_of_phys_memory);
-
- /* Reserve the kernel text/data/bss. */
- size = (start_pfn << PAGE_SHIFT) - phys_base;
- memblock_reserve(phys_base, size);
- memblock_add(phys_base, size);
-
- size = memblock_phys_mem_size() - memblock_reserved_size();
- *pages_avail = (size >> PAGE_SHIFT) - high_pages;
-
- /* Only allow low memory to be allocated via memblock allocation */
- memblock_set_current_limit(max_low_pfn << PAGE_SHIFT);
-
- return max_pfn;
-}
-
/*
* paging_init() sets up the page tables: We call the MMU specific
* init routine based upon the Sun model type on the Sparc.
@@ -220,14 +92,10 @@ void __init paging_init(void)
static void __init taint_real_pages(void)
{
- int i;
-
- for (i = 0; sp_banks[i].num_bytes; i++) {
- unsigned long start, end;
-
- start = sp_banks[i].base_addr;
- end = start + sp_banks[i].num_bytes;
+ phys_addr_t start, end;
+ u64 i;
+ for_each_mem_range(i, &start, &end) {
while (start < end) {
set_bit(start >> 20, sparc_valid_addr_bitmap);
start += PAGE_SIZE;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 3029527a5a9f..272e430f8bd8 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -884,7 +884,6 @@ void __init srmmu_paging_init(void)
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- unsigned long pages_avail;
init_mm.context = (unsigned long) NO_CONTEXT;
sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */
@@ -910,9 +909,6 @@ void __init srmmu_paging_init(void)
prom_halt();
}
- pages_avail = 0;
- last_valid_pfn = bootmem_init(&pages_avail);
-
srmmu_nocache_calcsize();
srmmu_nocache_init();
srmmu_inherit_prom_mappings(0xfe400000, (LINUX_OPPROM_ENDVM - PAGE_SIZE));
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] sparc32: drop sp_banks
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
` (3 preceding siblings ...)
2026-08-27 18:24 ` [PATCH 4/5] sparc32: move early memory setup to setup_arch Magnus Lindholm
@ 2026-08-27 18:24 ` Magnus Lindholm
4 siblings, 0 replies; 6+ messages in thread
From: Magnus Lindholm @ 2026-08-27 18:24 UTC (permalink / raw)
To: sparclinux; +Cc: davem, andreas, linux-kernel, sam, Magnus Lindholm
All memory-map consumers now use memblock. Stop duplicating the PROM map
in sp_banks and remove the array, its type, and its fixed bank limit.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
arch/sparc/include/asm/page_32.h | 16 -----------
arch/sparc/mm/init_32.c | 2 --
arch/sparc/prom/memory.c | 48 ++++----------------------------
3 files changed, 6 insertions(+), 60 deletions(-)
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index c1bccbedf567..5daa5fd8eaa5 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -26,22 +26,6 @@
sparc_flush_page_to_ram(page); \
} while (0)
-/* The following structure is used to hold the physical
- * memory configuration of the machine. This is filled in
- * prom_meminit() and is later used by mem_init() to set up
- * mem_map[]. We statically allocate SPARC_PHYS_BANKS+1 of
- * these structs, this is arbitrary. The entry after the
- * last valid one has num_bytes==0.
- */
-struct sparc_phys_banks {
- unsigned long base_addr;
- unsigned long num_bytes;
-};
-
-#define SPARC_PHYS_BANKS 32
-
-extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
-
/* passing structs on the Sparc slow us down tremendously... */
/* #define STRICT_MM_TYPECHECKS */
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 62c41d896421..4fc77ccedcbd 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -39,8 +39,6 @@
static unsigned long *sparc_valid_addr_bitmap;
-struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
-
/* Initial ramdisk setup */
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index 59962bc0bc82..3f65bde2bb89 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -8,30 +8,21 @@
#include <linux/kernel.h>
#include <linux/memblock.h>
-#include <linux/sort.h>
#include <linux/init.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/page.h>
-static int __init prom_meminit_v0(void)
+static void __init prom_meminit_v0(void)
{
struct linux_mlist_v0 *p;
- int index;
- index = 0;
- for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) {
- sp_banks[index].base_addr = (unsigned long) p->start_adr;
- sp_banks[index].num_bytes = p->num_bytes;
+ for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more)
memblock_add(p->start_adr, p->num_bytes & PAGE_MASK);
- index++;
- }
-
- return index;
}
-static int __init prom_meminit_v2(void)
+static void __init prom_meminit_v2(void)
{
struct linux_prom_registers reg[64];
phandle node;
@@ -41,51 +32,24 @@ static int __init prom_meminit_v2(void)
size = prom_getproperty(node, "available", (char *) reg, sizeof(reg));
num_ents = size / sizeof(struct linux_prom_registers);
- for (i = 0; i < num_ents; i++) {
- sp_banks[i].base_addr = reg[i].phys_addr;
- sp_banks[i].num_bytes = reg[i].reg_size;
+ for (i = 0; i < num_ents; i++)
memblock_add(reg[i].phys_addr, reg[i].reg_size & PAGE_MASK);
- }
-
- return num_ents;
-}
-
-static int sp_banks_cmp(const void *a, const void *b)
-{
- const struct sparc_phys_banks *x = a, *y = b;
-
- if (x->base_addr > y->base_addr)
- return 1;
- if (x->base_addr < y->base_addr)
- return -1;
- return 0;
}
/* Initialize the memory lists based upon the prom version. */
void __init prom_meminit(void)
{
- int i, num_ents = 0;
-
switch (prom_vers) {
case PROM_V0:
- num_ents = prom_meminit_v0();
+ prom_meminit_v0();
break;
case PROM_V2:
case PROM_V3:
- num_ents = prom_meminit_v2();
+ prom_meminit_v2();
break;
default:
break;
}
- sort(sp_banks, num_ents, sizeof(struct sparc_phys_banks),
- sp_banks_cmp, NULL);
-
- /* Sentinel. */
- sp_banks[num_ents].base_addr = 0xdeadbeef;
- sp_banks[num_ents].num_bytes = 0;
-
- for (i = 0; i < num_ents; i++)
- sp_banks[i].num_bytes &= PAGE_MASK;
}
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-27 18:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-27 18:24 [PATCH 0/5] sparc32: replace sp_banks with memblock Magnus Lindholm
2026-08-27 18:24 ` [PATCH 1/5] sparc32: use memblock when mapping the kernel Magnus Lindholm
2026-08-27 18:24 ` [PATCH 2/5] sparc32: use memblock to find available system memory Magnus Lindholm
2026-08-27 18:24 ` [PATCH 3/5] sparc32: populate memblock from the PROM memory map Magnus Lindholm
2026-08-27 18:24 ` [PATCH 4/5] sparc32: move early memory setup to setup_arch Magnus Lindholm
2026-08-27 18:24 ` [PATCH 5/5] sparc32: drop sp_banks Magnus Lindholm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®