The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v2 0/3] sparc32: allow a kernel loaded away from the start of RAM
@ 2026-08-16  7:50 Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 1/3] sparc32: honour phys_base in the viking cache flush routines Magnus Lindholm
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Magnus Lindholm @ 2026-08-16  7:50 UTC (permalink / raw)
  To: davem, andreas; +Cc: sparclinux, linux-kernel, Magnus Lindholm

Many years ago I ran Linux on my SPARCstation hardware and tried to keep
up with new releases, but somewhere around 3.x I hit a wall, sooner for
SMP builds since they are larger. As the kernel grew it simply became too
big for SILO to load. On this machine the last one that fit was 2.6.32,
at 2598956 bytes against a 2605056 byte window: six kilobytes to spare.
3.12 was 184KB over. Fixing it turned out to need more than SILO changes,
the kernel side needed work too, and I never got around to giving it
serious thought. I recently dusted off my old SPARCs and picked the
journey back up.

A current sparc32 kernel no longer fits in the window SILO loads into:
0x4000 up to SILO's own text at 0x280000, about 2.5MB. Loading it higher
instead exposes two places that assume the kernel sits at the start of
RAM.

Patch 1 is an independent pre-existing bug. viking_flush_page() and
viking_mxcc_flush_page() compute a physical address as vaddr -
PAGE_OFFSET, which is __pa() without phys_base. It is wrong regardless of
the rest of this series; it simply cannot be observed while phys_base is
zero. When it is not, iommu_flush_iotlb() flushes the wrong page, the
IOMMU walks stale IOPTEs and every DMA transfer fails. It comes first so
that no commit in the series leaves Viking DMA broken.

Patch 2 makes setup_arch() discover a non-zero phys_base. It takes it from
the lowest sp_banks[] entry today, and phys_base is the offset __pa() and
__va() are defined in terms of, so once the kernel is loaded elsewhere
every early translation is wrong by the difference, including the physical
addresses written into page table descriptors. The tablewalker then
follows pointers into pages holding nothing, while the same tables read
back correctly through the nocache view, and the machine stops right after
the context table pointer is installed with no console left to say why.
The probe is the architecture's existing __get_phys(), which already
implements it for sun4m and sun4d and returns zero elsewhere.

Patch 3 sets HdrS to 0x0300, the protocol level that tells a boot loader
the kernel supports being located somewhere other than physical 0x4000.

No change in behaviour when phys_base is zero.

Changes since v1:
 - drop the (unsigned int) casts and print with %lx (Sam Ravnborg)
 - always report RAM start and kernel start, not only when they differ
   (Sam Ravnborg). Note this means one line at every sparc32 boot; on
   platforms where __get_phys() is not implemented it reads as
   "kernel is at 0x0".
 - collect Reviewed-by from Sam Ravnborg on patches 1 and 3

Patches 1 and 3 are unchanged from v1 apart from the collected tag.

Tested on a SPARCstation 20 booting from SCSI to a full userspace, with
and without an initramfs, using a SILO carrying the matching loader
changes. Also boot tested under qemu-system-sparc -M SS-5, and build
tested for LEON and plain sparc32_defconfig. Each commit builds on its
own. Emulation cannot exercise patch 1: microSPARC-II takes a different
cache flush path, and qemu models no write-back cache, so a missed flush
has no consequence there.

The cost is the RAM below the load address, which the loader chooses.

Magnus Lindholm (3):
  sparc32: honour phys_base in the viking cache flush routines
  sparc32: derive phys_base from the PAGE_OFFSET mapping
  sparc32: advertise relocatable kernel with HdrS 0x0300

 arch/sparc/kernel/head_32.S  |  2 +-
 arch/sparc/kernel/setup_32.c | 40 ++++++++++++++++++++++++++++++++++++
 arch/sparc/mm/viking.S       |  6 ++++++
 3 files changed, 47 insertions(+), 1 deletion(-)

--
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] sparc32: honour phys_base in the viking cache flush routines
  2026-08-16  7:50 [PATCH v2 0/3] sparc32: allow a kernel loaded away from the start of RAM Magnus Lindholm
@ 2026-08-16  7:50 ` Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 3/3] sparc32: advertise relocatable kernel with HdrS 0x0300 Magnus Lindholm
  2 siblings, 0 replies; 7+ messages in thread
From: Magnus Lindholm @ 2026-08-16  7:50 UTC (permalink / raw)
  To: davem, andreas; +Cc: sparclinux, linux-kernel, Magnus Lindholm, Sam Ravnborg

viking_flush_page() and viking_mxcc_flush_page() derive the physical
address of the page they are asked to flush by subtracting PAGE_OFFSET
from the kernel virtual address:

	sethi	%hi(PAGE_OFFSET), %g2
	sub	%o0, %g2, %g3

That is only the physical address when phys_base is zero. The C side spells
the same conversion __pa(), which adds phys_base, and every caller passes a
kernel virtual address expecting exactly that.

With a kernel loaded away from the start of RAM the two disagree by
phys_base. viking_flush_page() then compares cache tags against the wrong
page and flushes nothing, and viking_mxcc_flush_page() streams a page that
is phys_base lower than the one it was given, so the intended lines stay
dirty in the cache while unrelated ones are pushed out.

The visible effect is that anything relying on a flush to make memory
visible to another bus master silently keeps working from stale data. On a
SPARCstation 20 this shows up as every SCSI transfer failing with a DMA
error: iommu_flush_iotlb() cannot get the IOPTEs out to RAM, so the IOMMU
walks stale entries and the ESP DMA faults.

Add phys_base, so these agree with __pa() again. No change when phys_base
is zero, which is why this went unnoticed.

Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
 arch/sparc/mm/viking.S | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S
index 48f062de7a7f..8b4e251bbba2 100644
--- a/arch/sparc/mm/viking.S
+++ b/arch/sparc/mm/viking.S
@@ -38,6 +38,9 @@ sun4dsmp_flush_tlb_spin:
 viking_flush_page:
 	sethi	%hi(PAGE_OFFSET), %g2
 	sub	%o0, %g2, %g3
+	sethi	%hi(phys_base), %g2
+	ld	[%g2 + %lo(phys_base)], %g2
+	add	%g3, %g2, %g3		! + phys_base = physical address
 	srl	%g3, 12, %g1		! ppage >> 12
 
 	clr	%o1			! set counter, 0 - 127
@@ -91,6 +94,9 @@ viking_flush_page:
 viking_mxcc_flush_page:
 	sethi	%hi(PAGE_OFFSET), %g2
 	sub	%o0, %g2, %g3
+	sethi	%hi(phys_base), %g2
+	ld	[%g2 + %lo(phys_base)], %g2
+	add	%g3, %g2, %g3			! + phys_base = physical address
 	sub	%g3, -PAGE_SIZE, %g3		! ppage + PAGE_SIZE
 	sethi	%hi(MXCC_SRCSTREAM), %o3	! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM)
 	mov	0x10, %g2			! set cacheable bit
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping
  2026-08-16  7:50 [PATCH v2 0/3] sparc32: allow a kernel loaded away from the start of RAM Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 1/3] sparc32: honour phys_base in the viking cache flush routines Magnus Lindholm
@ 2026-08-16  7:50 ` Magnus Lindholm
  2026-08-16 19:54   ` Sam Ravnborg
  2026-08-16  7:50 ` [PATCH v2 3/3] sparc32: advertise relocatable kernel with HdrS 0x0300 Magnus Lindholm
  2 siblings, 1 reply; 7+ messages in thread
From: Magnus Lindholm @ 2026-08-16  7:50 UTC (permalink / raw)
  To: davem, andreas; +Cc: sparclinux, linux-kernel, Magnus Lindholm

setup_arch() computes phys_base as the base of the lowest sp_banks[]
entry, that is, where RAM starts, and assumes the kernel image was loaded
there. That holds for the traditional boot path, where SILO places the
image at physical 0x4000 and PAGE_OFFSET is mapped to physical 0.

It stops holding once the image no longer fits there. SILO loads a kernel
between physical 0x4000 and its own text at 0x280000, a window of 2605056
bytes; a current sparc32 kernel is roughly twice that. The loader must
then place the image elsewhere in physical memory and map PAGE_OFFSET to
it, at which point phys_base describes where RAM begins rather than what
PAGE_OFFSET maps to, and the two disagree.

phys_base is the offset __pa() and __va() are defined in terms of, so once
it is wrong every early translation is wrong by the difference, including
the physical addresses written into page table descriptors. The
tablewalker then follows pointers into pages that hold nothing while the
same tables read back correctly through the nocache view. The failure
surfaces as a hang right after the context table pointer is installed and
the TLB flushed, with nothing on the console to explain it, since the PROM
mappings the early console depends on have become just as unreachable.

Ask the MMU what PAGE_OFFSET actually translates to and adopt that.
__get_phys() already implements this probe for sun4m and sun4d and returns
zero elsewhere, so no new low level MMU access is introduced and machines
without an SRMMU are unaffected.

Memory below the kernel cannot be reached through the linear map, which
runs upward from PAGE_OFFSET, so drop the banks that fall below it rather
than leave entries that __va() would translate to below PAGE_OFFSET.

With this a 6MB kernel loaded at physical 0x03000000 boots on sun4m: the
context table lands at its true physical address,
srmmu_inherit_prom_mappings() preserves the PROM console mappings, and
srmmu.c needs no change at all, since map_kernel() already handles a
non-zero phys_base via do_large_mapping().

The cost is the RAM below the load address the loader chose. SILO's
memory_find() picks 48MB on machines with 64MB or more.

Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
 arch/sparc/kernel/setup_32.c | 40 ++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 1b0db16cd37b..34e8f7c87685 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -254,6 +254,30 @@ 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)
+{
+	int i, j = 0;
+
+	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;
+
+		if (end <= base)
+			continue;		/* wholly below - drop it */
+		if (start < base)
+			start = base;		/* straddles - trim the front */
+
+		sp_banks[j].base_addr = start;
+		sp_banks[j].num_bytes = end - start;
+		j++;
+	}
+	sp_banks[j].base_addr = 0;
+	sp_banks[j].num_bytes = 0;
+}
+
 /* Called from head_32.S - before we have setup anything
  * in the kernel. Be very careful with what you do here.
  */
@@ -332,6 +356,22 @@ void __init setup_arch(char **cmdline_p)
 		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);
+
+		prom_printf("phys_base: RAM starts 0x%lx, kernel is at 0x%lx\n",
+			    phys_base, real_base);
+
+		if (real_base && real_base != phys_base) {
+			phys_base = real_base;
+			trim_sp_banks_below(phys_base);
+			prom_printf("phys_base: adopted 0x%lx, RAM below it dropped\n",
+				    phys_base);
+		}
+	}
+
 	pfn_base = phys_base >> PAGE_SHIFT;
 
 	if (!root_flags)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] sparc32: advertise relocatable kernel with HdrS 0x0300
  2026-08-16  7:50 [PATCH v2 0/3] sparc32: allow a kernel loaded away from the start of RAM Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 1/3] sparc32: honour phys_base in the viking cache flush routines Magnus Lindholm
  2026-08-16  7:50 ` [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping Magnus Lindholm
@ 2026-08-16  7:50 ` Magnus Lindholm
  2 siblings, 0 replies; 7+ messages in thread
From: Magnus Lindholm @ 2026-08-16  7:50 UTC (permalink / raw)
  To: davem, andreas; +Cc: sparclinux, linux-kernel, Magnus Lindholm, Sam Ravnborg

HdrS version 0x0300 tells the boot loader that the kernel supports being
located somewhere other than physical 0x4000, which is where SILO places
the image on the traditional path. Anything older is copied back down
there, and refused outright when it no longer fits.

sparc32 could not make that claim before, because setup_arch() took
phys_base from the lowest memory bank rather than from what PAGE_OFFSET
maps to. It can now, so say so.

Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
 arch/sparc/kernel/head_32.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 8c320fa25a67..11a1746829a4 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -69,7 +69,7 @@ sun4e_notsup:
  */
 	.ascii	"HdrS"
 	.word	LINUX_VERSION_CODE
-	.half	0x0203		/* HdrS version */
+	.half	0x0300		/* HdrS version */
 root_flags:
 	.half	1
 root_dev:
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping
  2026-08-16  7:50 ` [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping Magnus Lindholm
@ 2026-08-16 19:54   ` Sam Ravnborg
  2026-08-16 20:56     ` Magnus Lindholm
  0 siblings, 1 reply; 7+ messages in thread
From: Sam Ravnborg @ 2026-08-16 19:54 UTC (permalink / raw)
  To: Magnus Lindholm; +Cc: davem, andreas, sparclinux, linux-kernel

Hi Magnus.

On Sun, Aug 16, 2026 at 09:50:16AM +0200, Magnus Lindholm wrote:
> setup_arch() computes phys_base as the base of the lowest sp_banks[]
> entry, that is, where RAM starts, and assumes the kernel image was loaded
> there. That holds for the traditional boot path, where SILO places the
> image at physical 0x4000 and PAGE_OFFSET is mapped to physical 0.
> 
> It stops holding once the image no longer fits there. SILO loads a kernel
> between physical 0x4000 and its own text at 0x280000, a window of 2605056
> bytes; a current sparc32 kernel is roughly twice that. The loader must
> then place the image elsewhere in physical memory and map PAGE_OFFSET to
> it, at which point phys_base describes where RAM begins rather than what
> PAGE_OFFSET maps to, and the two disagree.
> 
> phys_base is the offset __pa() and __va() are defined in terms of, so once
> it is wrong every early translation is wrong by the difference, including
> the physical addresses written into page table descriptors. The
> tablewalker then follows pointers into pages that hold nothing while the
> same tables read back correctly through the nocache view. The failure
> surfaces as a hang right after the context table pointer is installed and
> the TLB flushed, with nothing on the console to explain it, since the PROM
> mappings the early console depends on have become just as unreachable.
> 
> Ask the MMU what PAGE_OFFSET actually translates to and adopt that.
> __get_phys() already implements this probe for sun4m and sun4d and returns
> zero elsewhere, so no new low level MMU access is introduced and machines
> without an SRMMU are unaffected.
> 
> Memory below the kernel cannot be reached through the linear map, which
> runs upward from PAGE_OFFSET, so drop the banks that fall below it rather
> than leave entries that __va() would translate to below PAGE_OFFSET.
> 
> With this a 6MB kernel loaded at physical 0x03000000 boots on sun4m: the
> context table lands at its true physical address,
> srmmu_inherit_prom_mappings() preserves the PROM console mappings, and
> srmmu.c needs no change at all, since map_kernel() already handles a
> non-zero phys_base via do_large_mapping().
The patch looks good but I dislike we introduce more code that uses
sp_banks. Can we somehow use memblock for this?

Part of my old grand plan was to replace all uses of sp_banks with
memblock. I have some old patches somewhere in case you are ready to
give this a spin.

The patch is:
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

My sp_banks comment shall not hold it back.
It is anyway Andreas that will handle them.

	Sam

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping
  2026-08-16 19:54   ` Sam Ravnborg
@ 2026-08-16 20:56     ` Magnus Lindholm
  2026-08-17 15:32       ` Sam Ravnborg
  0 siblings, 1 reply; 7+ messages in thread
From: Magnus Lindholm @ 2026-08-16 20:56 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: davem, andreas, sparclinux, linux-kernel

On Sun, Aug 16, 2026 at 9:54 PM Sam Ravnborg <sam@ravnborg.org> wrote:

> sp_banks. Can we somehow use memblock for this?
>
> Part of my old grand plan was to replace all uses of sp_banks with
> memblock. I have some old patches somewhere in case you are ready to
> give this a spin.
>
> The patch is:
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
>
> My sp_banks comment shall not hold it back.
> It is anyway Andreas that will handle them.
>

Thanks a lot for taking the time to review this series.

Moving sparc32 off sp_banks and onto memblock sounds like the right
direction, setup_arch() already had the array to hand, which is the only
reason this patch reaches for it. I'd be glad to pick up your old patches
and take them for a spin, just point me at where I can find them.

Magnus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping
  2026-08-16 20:56     ` Magnus Lindholm
@ 2026-08-17 15:32       ` Sam Ravnborg
  0 siblings, 0 replies; 7+ messages in thread
From: Sam Ravnborg @ 2026-08-17 15:32 UTC (permalink / raw)
  To: Magnus Lindholm; +Cc: davem, andreas, sparclinux, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 754 bytes --]

Hi Magnus.

> Moving sparc32 off sp_banks and onto memblock sounds like the right
> direction, setup_arch() already had the array to hand, which is the only
> reason this patch reaches for it. I'd be glad to pick up your old patches
> and take them for a spin, just point me at where I can find them.

The patches are likely online somewhere, but I found the relevant ones
that I have attached here.

These are from the middle of my sun4m/sun4d removal patches, expect
parts to be missed out and for sure they do not apply in your tree.

I recall they were tested one-by-one via QEMU, but I did not test on
real HW.

Feel free to claim full authorship on patches where you do anything
than trivial edits.

I hope you will have fun working on this.

	Sam

[-- Attachment #2: 0001-sparc32-Use-memblock-when-mapping-the-kernel.patch --]
[-- Type: text/x-diff, Size: 2474 bytes --]

From 6fdce3fcdc4f504b27366c56c53df337631d31b1 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 09:06:19 +0100
Subject: [PATCH 1/8] sparc32: Use memblock when mapping the kernel

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/mm/srmmu.c | 48 ++++++++++++++++++++-----------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index fc2012eb7606..d22b5f09ba20 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -695,39 +695,35 @@ 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 + 1));
+
+		/* 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)
+			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.53.0


[-- Attachment #3: 0002-sparc32-Use-memblock-to-find-the-available-system-me.patch --]
[-- Type: text/x-diff, Size: 1393 bytes --]

From fbd887c2f0b372e1a8326e0dec24c2208de9ecdf Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 09:12:49 +0100
Subject: [PATCH 2/8] sparc32: Use memblock to find the available system memory

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.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 d22b5f09ba20..67a4f1f74dc3 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -186,25 +186,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.53.0


[-- Attachment #4: 0003-sparc32-Move-bootmem_init-to-setup_memory.patch --]
[-- Type: text/x-diff, Size: 3073 bytes --]

From 33f6bfc6be9152c529adb9d7ce18e6db2c57c3dd Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 13:19:42 +0100
Subject: [PATCH 3/8] sparc32: Move bootmem_init to setup_memory

Move it away from srmmu, so we can have more of the memory handling in
one place.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/include/asm/pgtable_32.h | 2 +-
 arch/sparc/kernel/setup_32.c        | 2 ++
 arch/sparc/mm/init_32.c             | 5 +----
 arch/sparc/mm/srmmu.c               | 4 ----
 4 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 40cdca44ea63..d353fdfa1c61 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -38,7 +38,7 @@ struct page;
 
 void load_mmu(void);
 unsigned long calc_highpages(void);
-unsigned long __init bootmem_init(unsigned long *pages_avail);
+void __init bootmem_init(void);
 
 #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 0ec597b2a567..75c36f734dfb 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -209,6 +209,8 @@ static void __init setup_memory(void)
 	/* Lowest address available */
 	phys_base = memblock_start_of_DRAM();
 	pfn_base = min_low_pfn;
+
+	bootmem_init();
 }
 
 void __init setup_arch(char **cmdline_p)
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index bd42fb1611e7..ebaa2ba2f318 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -118,7 +118,7 @@ static void __init find_ramdisk(unsigned long end_of_phys_memory)
 #endif
 }
 
-unsigned long __init bootmem_init(unsigned long *pages_avail)
+void __init bootmem_init(void)
 {
 	unsigned long start_pfn, bytes_avail, size;
 	unsigned long end_of_phys_memory = 0;
@@ -178,12 +178,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
 	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;
 }
 
 /*
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 67a4f1f74dc3..dfe5bae5aee9 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -727,7 +727,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. */
@@ -749,9 +748,6 @@ void __init srmmu_paging_init(void)
 		prom_halt();
 	}
 
-	pages_avail = 0;
-	bootmem_init(&pages_avail);
-
 	srmmu_nocache_calcsize();
 	srmmu_nocache_init();
 	srmmu_inherit_prom_mappings(0xfe400000, (LINUX_OPPROM_ENDVM - PAGE_SIZE));
-- 
2.53.0


[-- Attachment #5: 0004-sparc32-Drop-printing-HIGHMEM-available.patch --]
[-- Type: text/x-diff, Size: 2316 bytes --]

From d60b1c299e23d7f77b14ed3a36b0b1db2f89d409 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 13:26:49 +0100
Subject: [PATCH 4/8] sparc32: Drop printing HIGHMEM available

The kernel will tell us, there is no need to print it twice.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/include/asm/pgtable_32.h |  1 -
 arch/sparc/mm/init_32.c             | 25 -------------------------
 2 files changed, 26 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index d353fdfa1c61..533f842ef5fe 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -37,7 +37,6 @@ struct vm_area_struct;
 struct page;
 
 void load_mmu(void);
-unsigned long calc_highpages(void);
 void __init bootmem_init(void);
 
 #define pte_ERROR(e)   __builtin_trap()
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index ebaa2ba2f318..b5dd819dc314 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -45,27 +45,6 @@ extern unsigned int sparc_ramdisk_size;
 
 unsigned long highstart_pfn, highend_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;
@@ -122,7 +101,6 @@ void __init bootmem_init(void)
 {
 	unsigned long start_pfn, bytes_avail, size;
 	unsigned long end_of_phys_memory = 0;
-	unsigned long high_pages = 0;
 	int i;
 
 	bytes_avail = 0UL;
@@ -165,9 +143,6 @@ void __init bootmem_init(void)
 	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);
-- 
2.53.0


[-- Attachment #6: 0005-sparc32-Use-memblock-when-freeing-highmem-pages.patch --]
[-- Type: text/x-diff, Size: 2233 bytes --]

From a982b119e333c09a99d82cc3b6e9b5cec25c218e Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 13:56:43 +0100
Subject: [PATCH 5/8] sparc32: Use memblock when freeing highmem pages

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/mm/init_32.c | 34 ++++++++++++++--------------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index b5dd819dc314..a55d34c94d12 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -171,21 +171,10 @@ void __init paging_init(void)
 	device_scan();
 }
 
-static void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
-{
-	unsigned long tmp;
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-	printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn);
-#endif
-
-	for (tmp = start_pfn; tmp < end_pfn; tmp++)
-		free_highmem_page(pfn_to_page(tmp));
-}
-
 void __init mem_init(void)
 {
-	int i;
+	phys_addr_t range_start, range_end;
+	u64 i;
 
 	if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
 		prom_printf("BUG: fixmap and pkmap areas overlap\n");
@@ -202,20 +191,25 @@ void __init mem_init(void)
 	memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
 	max_mapnr = max_pfn - pfn_base;
+
 	high_memory = __va(max_low_pfn << PAGE_SHIFT);
 	memblock_free_all();
 
-	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;
+	for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
+				&range_start, &range_end, NULL) {
+		unsigned long start = PFN_UP(range_start);
+		unsigned long end = PFN_DOWN(range_end);
 
-		if (end_pfn <= highstart_pfn)
+		/* Ignore complete lowmem entries */
+		if (end <= max_low_pfn)
 			continue;
 
-		if (start_pfn < highstart_pfn)
-			start_pfn = highstart_pfn;
+		/* Truncate partial highmem entries */
+		if (start < max_low_pfn)
+			start = max_low_pfn;
 
-		map_high_region(start_pfn, end_pfn);
+		for (; start < end; start++)
+			free_highmem_page(pfn_to_page(start));
 	}
 }
 
-- 
2.53.0


[-- Attachment #7: 0006-sparc32-Drop-mem-support.patch --]
[-- Type: text/x-diff, Size: 3943 bytes --]

From 7fe5051929add5ef30982c174434e7d7cff52a2e Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 19:05:24 +0100
Subject: [PATCH 6/8] sparc32: Drop mem= support

If there is a need to limit the memory available the feature
can be added later using early_param support etc.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/include/asm/setup.h |  3 ---
 arch/sparc/kernel/setup_32.c   | 18 ------------------
 arch/sparc/mm/init_32.c        | 32 +++-----------------------------
 3 files changed, 3 insertions(+), 50 deletions(-)

diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 72205684e51e..e6f7eb383b1f 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -37,9 +37,6 @@ extern unsigned long pdma_areasize;
 
 int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
 
-/* setup_32.c */
-extern unsigned long cmdline_memory_size;
-
 /* devices.c */
 void __init device_scan(void);
 
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 75c36f734dfb..c8b3e19472af 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -88,9 +88,6 @@ static void prom_sync_me(void)
 static unsigned int boot_flags __initdata = 0;
 #define BOOTME_DEBUG  0x1
 
-/* Exported for mm/init.c:paging_init. */
-unsigned long cmdline_memory_size __initdata = 0;
-
 /* which CPU booted us (0xff = not set) */
 unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */
 
@@ -148,21 +145,6 @@ static void __init boot_flags_init(char *commands)
 				process_switch(*commands++);
 			continue;
 		}
-		if (!strncmp(commands, "mem=", 4)) {
-			/*
-			 * "mem=XXX[kKmM] overrides the PROM-reported
-			 * memory size.
-			 */
-			cmdline_memory_size = simple_strtoul(commands + 4,
-						     &commands, 0);
-			if (*commands == 'K' || *commands == 'k') {
-				cmdline_memory_size <<= 10;
-				commands++;
-			} else if (*commands=='M' || *commands=='m') {
-				cmdline_memory_size <<= 20;
-				commands++;
-			}
-		}
 		while (*commands && *commands != ' ')
 			commands++;
 	}
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index a55d34c94d12..cd16e9ae81b6 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -99,33 +99,7 @@ static void __init find_ramdisk(unsigned long end_of_phys_memory)
 
 void __init bootmem_init(void)
 {
-	unsigned long start_pfn, bytes_avail, size;
-	unsigned long end_of_phys_memory = 0;
-	int i;
-
-	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 {
-					sp_banks[i+1].num_bytes = 0;
-					sp_banks[i+1].base_addr = 0xdeadbeef;
-				}
-				break;
-			}
-		}
-	}
+	unsigned long start_pfn, size;
 
 	/* Start with page aligned address of last symbol in kernel
 	 * image.
@@ -135,7 +109,7 @@ void __init bootmem_init(void)
 	/* Now shift down to get the real physical page frame number. */
 	start_pfn >>= PAGE_SHIFT;
 
-	max_pfn = end_of_phys_memory >> PAGE_SHIFT;
+	max_pfn = PFN_DOWN(memblock_end_of_DRAM());
 
 	max_low_pfn = max_pfn;
 	highstart_pfn = highend_pfn = max_pfn;
@@ -145,7 +119,7 @@ void __init bootmem_init(void)
 		max_low_pfn = calc_max_low_pfn();
 	}
 
-	find_ramdisk(end_of_phys_memory);
+	find_ramdisk(memblock_end_of_DRAM());
 
 	/* Reserve the kernel text/data/bss. */
 	size = (start_pfn << PAGE_SHIFT) - phys_base;
-- 
2.53.0


[-- Attachment #8: 0007-sparc32-Move-memory-config-to-setup_32.patch --]
[-- Type: text/x-diff, Size: 5293 bytes --]

From 3afe806edfda93fcdf137e55b2653c74c5e54b66 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 19:27:15 +0100
Subject: [PATCH 7/8] sparc32: Move memory config to setup_32

Move all early memory configuration to setup_memory.
Replace sp_banks use with memblock.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/include/asm/pgtable_32.h |  2 +-
 arch/sparc/kernel/setup_32.c        | 44 ++++++++++++++++++++-
 arch/sparc/mm/init_32.c             | 61 +----------------------------
 3 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 533f842ef5fe..ac92e4801d10 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -37,7 +37,7 @@ struct vm_area_struct;
 struct page;
 
 void load_mmu(void);
-void __init bootmem_init(void);
+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 c8b3e19472af..79dcd564a919 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -172,14 +172,41 @@ void __init sparc32_start_kernel(struct linux_romvec *rp)
 	start_kernel();
 }
 
+static unsigned long calc_max_low_pfn(void)
+{
+	unsigned long tmp = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
+	unsigned long last_pfn = 0;
+	unsigned long curr_pfn;
+	phys_addr_t start, end;
+	u64 i;
+
+	for_each_mem_range(i, &start, &end) {
+		curr_pfn = PFN_DOWN(start);
+
+		if (curr_pfn >= tmp) {
+			if (last_pfn < tmp)
+				tmp = last_pfn;
+			break;
+		}
+
+		last_pfn = PFN_DOWN(start + end + 1);
+	}
+
+	return tmp;
+}
+
 unsigned long phys_base;
 EXPORT_SYMBOL(phys_base);
 
 unsigned long pfn_base;
 EXPORT_SYMBOL(pfn_base);
 
+unsigned long highend_pfn;
+
 static void __init setup_memory(void)
 {
+	unsigned long size;
+
 	memblock_set_bottom_up(true);
 	memblock_allow_resize();
 
@@ -187,12 +214,27 @@ static void __init setup_memory(void)
 
 	/* Setup memblock globals */
 	min_low_pfn = PFN_DOWN(memblock_start_of_DRAM());
+	max_pfn = PFN_DOWN(memblock_end_of_DRAM());
+	max_low_pfn = max_pfn;
 
 	/* Lowest address available */
 	phys_base = memblock_start_of_DRAM();
 	pfn_base = min_low_pfn;
 
-	bootmem_init();
+	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 via memblock allocation */
+	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
 }
 
 void __init setup_arch(char **cmdline_p)
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index cd16e9ae81b6..74174d20e566 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -43,31 +43,7 @@ struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
 extern unsigned int sparc_ramdisk_image;
 extern unsigned int sparc_ramdisk_size;
 
-unsigned long highstart_pfn, highend_pfn;
-
-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;
@@ -97,41 +73,6 @@ static void __init find_ramdisk(unsigned long end_of_phys_memory)
 #endif
 }
 
-void __init bootmem_init(void)
-{
-	unsigned long start_pfn, 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 = PFN_DOWN(memblock_end_of_DRAM());
-
-	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();
-	}
-
-	find_ramdisk(memblock_end_of_DRAM());
-
-	/* 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();
-
-	/* Only allow low memory to be allocated via memblock allocation */
-	memblock_set_current_limit(max_low_pfn << PAGE_SHIFT);
-}
-
 /*
  * paging_init() sets up the page tables: We call the MMU specific
  * init routine based upon the Sun model type on the Sparc.
-- 
2.53.0


[-- Attachment #9: 0008-sparc32-Drop-sp_banks.patch --]
[-- Type: text/x-diff, Size: 4055 bytes --]

From 8befec09894be332e50de7d14a846e50083f5667 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@ravnborg.org>
Date: Sun, 31 Dec 2023 19:34:43 +0100
Subject: [PATCH 8/8] sparc32: Drop sp_banks

memblock is now used all over as replacement for sp_banks.
Delete the remaining left-overs of sp_banks.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
---
 arch/sparc/include/asm/page_32.h | 16 -----------
 arch/sparc/mm/init_32.c          |  2 --
 arch/sparc/prom/memory.c         | 47 ++++----------------------------
 3 files changed, 6 insertions(+), 59 deletions(-)

diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index 9977c77374cd..557c0240d7e6 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -28,22 +28,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 74174d20e566..8c9f17731aee 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -37,8 +37,6 @@
 
 #include "mm_32.h"
 
-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 68cbad8f7ebf..d3e07e161ebc 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -15,23 +15,15 @@
 #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;
-		index++;
+	for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more)
 		memblock_add(p->start_adr, p->num_bytes);
-	}
-
-	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 +33,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);
-	}
-
-	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.53.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-08-17 15:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-16  7:50 [PATCH v2 0/3] sparc32: allow a kernel loaded away from the start of RAM Magnus Lindholm
2026-08-16  7:50 ` [PATCH v2 1/3] sparc32: honour phys_base in the viking cache flush routines Magnus Lindholm
2026-08-16  7:50 ` [PATCH v2 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping Magnus Lindholm
2026-08-16 19:54   ` Sam Ravnborg
2026-08-16 20:56     ` Magnus Lindholm
2026-08-17 15:32       ` Sam Ravnborg
2026-08-16  7:50 ` [PATCH v2 3/3] sparc32: advertise relocatable kernel with HdrS 0x0300 Magnus Lindholm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox