From: Sam Ravnborg <sam@ravnborg.org>
To: Magnus Lindholm <linmag7@gmail.com>
Cc: davem@davemloft.net, andreas@gaisler.com,
sparclinux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping
Date: Fri, 14 Aug 2026 22:46:52 +0200 [thread overview]
Message-ID: <20260814204652.GB534878@ravnborg.org> (raw)
In-Reply-To: <20260814105723.3454511-3-linmag7@gmail.com>
Hi Magnus.
On Fri, Aug 14, 2026 at 12:52:33PM +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 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..795714959da6 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;
> +}
OK
> +
> /* 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);
> +
> + 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);
Use 0x%xl to avoid the casts?
If we are noisy like this it would be nice to always print the RAM start
and kernel start.
The logic looks fine, just the few nits.
Sam
next prev parent reply other threads:[~2026-08-14 20:46 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 10:52 [PATCH 0/3] sparc32: allow a kernel loaded away from the start of RAM Magnus Lindholm
2026-08-14 10:52 ` [PATCH 1/3] sparc32: honour phys_base in the viking cache flush routines Magnus Lindholm
2026-08-14 20:43 ` Sam Ravnborg
2026-08-14 10:52 ` [PATCH 2/3] sparc32: derive phys_base from the PAGE_OFFSET mapping Magnus Lindholm
2026-08-14 20:46 ` Sam Ravnborg [this message]
2026-08-14 21:58 ` Magnus Lindholm
2026-08-14 10:52 ` [PATCH 3/3] sparc32: advertise relocatable kernel with HdrS 0x0300 Magnus Lindholm
2026-08-14 20:48 ` Sam Ravnborg
2026-08-14 11:25 ` [PATCH 0/3] sparc32: allow a kernel loaded away from the start of RAM John Paul Adrian Glaubitz
2026-08-14 14:18 ` Magnus Lindholm
2026-08-14 20:53 ` Sam Ravnborg
2026-08-14 22:05 ` Magnus Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814204652.GB534878@ravnborg.org \
--to=sam@ravnborg.org \
--cc=andreas@gaisler.com \
--cc=davem@davemloft.net \
--cc=linmag7@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sparclinux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®