linux/arch/xtensa/kernel/head.S
Mike Rapoport (Microsoft) 6215d9f447 arch, mm: consolidate empty_zero_page
Reduce 22 declarations of empty_zero_page to 3 and 23 declarations of
ZERO_PAGE() to 4.

Every architecture defines empty_zero_page that way or another, but for the
most of them it is always a page aligned page in BSS and most definitions
of ZERO_PAGE do virt_to_page(empty_zero_page).

Move Linus vetted x86 definition of empty_zero_page and ZERO_PAGE() to the
core MM and drop these definitions in architectures that do not implement
colored zero page (MIPS and s390).

ZERO_PAGE() remains a macro because turning it to a wrapper for a static
inline causes severe pain in header dependencies.

For the most part the change is mechanical, with these being noteworthy:

* alpha: aliased empty_zero_page with ZERO_PGE that was also used for boot
  parameters. Switching to a generic empty_zero_page removes the aliasing
  and keeps ZERO_PGE for boot parameters only
* arm64: uses __pa_symbol() in ZERO_PAGE() so that definition of
  ZERO_PAGE() is kept intact.
* m68k/parisc/um: allocated empty_zero_page from memblock,
  although they do not support zero page coloring and having it in BSS
  will work fine.
* sparc64 can have empty_zero_page in BSS rather allocate it, but it
  can't use virt_to_page() for BSS. Keep it's definition of ZERO_PAGE()
  but instead of allocating it, make mem_map_zero point to
  empty_zero_page.
* sh: used empty_zero_page for boot parameters at the very early boot.
  Rename the parameters page to boot_params_page and let sh use the generic
  empty_zero_page.
* hexagon: had an amusing comment about empty_zero_page

	/* A handy thing to have if one has the RAM. Declared in head.S */

  that unfortunately had to go :)

Link: https://lkml.kernel.org/r/20260211103141.3215197-4-rppt@kernel.org
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: Helge Deller <deller@gmx.de>		[parisc]
Tested-by: Helge Deller <deller@gmx.de>		[parisc]
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>	[alpha]
Acked-by: Dinh Nguyen <dinguyen@kernel.org>	[nios2]
Acked-by: Andreas Larsson <andreas@gaisler.com>	[sparc]
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: "Borislav Petkov (AMD)" <bp@alien8.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Stafford Horne <shorne@gmail.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vineet Gupta <vgupta@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-04-05 13:53:01 -07:00

384 lines
6.9 KiB
ArmAsm

/*
* arch/xtensa/kernel/head.S
*
* Xtensa Processor startup code.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 - 2008 Tensilica Inc.
*
* Chris Zankel <chris@zankel.net>
* Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
* Kevin Chea
*/
#include <asm/asmmacro.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/cacheasm.h>
#include <asm/initialize_mmu.h>
#include <asm/mxregs.h>
#include <linux/init.h>
#include <linux/linkage.h>
/*
* This module contains the entry code for kernel images. It performs the
* minimal setup needed to call the generic C routines.
*
* Prerequisites:
*
* - The kernel image has been loaded to the actual address where it was
* compiled to.
* - a2 contains either 0 or a pointer to a list of boot parameters.
* (see setup.c for more details)
*
*/
/*
* _start
*
* The bootloader passes a pointer to a list of boot parameters in a2.
*/
/* The first bytes of the kernel image must be an instruction, so we
* manually allocate and define the literal constant we need for a jx
* instruction.
*/
__HEAD
.begin no-absolute-literals
ENTRY(_start)
/* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
wsr a2, excsave1
_j _SetupOCD
.align 4
.literal_position
_SetupOCD:
/*
* Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
* Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
* xt-gdb to single step via DEBUG exceptions received directly
* by ocd.
*/
#if XCHAL_HAVE_WINDOWED
movi a1, 1
movi a0, 0
wsr a1, windowstart
wsr a0, windowbase
rsync
#endif
movi a1, LOCKLEVEL
wsr a1, ps
rsync
.global _SetupMMU
_SetupMMU:
Offset = _SetupMMU - _start
#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
initialize_mmu
#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
rsr a2, excsave1
movi a3, XCHAL_KSEG_PADDR
bltu a2, a3, 1f
sub a2, a2, a3
movi a3, XCHAL_KSEG_SIZE
bgeu a2, a3, 1f
movi a3, XCHAL_KSEG_CACHED_VADDR
add a2, a2, a3
wsr a2, excsave1
1:
#endif
#endif
movi a0, _startup
jx a0
ENDPROC(_start)
.end no-absolute-literals
__REF
.literal_position
ENTRY(_startup)
/* Set a0 to 0 for the remaining initialization. */
movi a0, 0
#if XCHAL_HAVE_VECBASE
movi a2, VECBASE_VADDR
wsr a2, vecbase
#endif
/* Clear debugging registers. */
#if XCHAL_HAVE_DEBUG
#if XCHAL_NUM_IBREAK > 0
wsr a0, ibreakenable
#endif
wsr a0, icount
movi a1, 15
wsr a0, icountlevel
.set _index, 0
.rept XCHAL_NUM_DBREAK
wsr a0, SREG_DBREAKC + _index
.set _index, _index + 1
.endr
#endif
/* Clear CCOUNT (not really necessary, but nice) */
wsr a0, ccount # not really necessary, but nice
/* Disable zero-loops. */
#if XCHAL_HAVE_LOOPS
wsr a0, lcount
#endif
/* Disable all timers. */
.set _index, 0
.rept XCHAL_NUM_TIMERS
wsr a0, SREG_CCOMPARE + _index
.set _index, _index + 1
.endr
/* Interrupt initialization. */
movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
wsr a0, intenable
wsr a2, intclear
/* Disable coprocessors. */
#if XCHAL_HAVE_CP
wsr a0, cpenable
#endif
/* Initialize the caches.
* a2, a3 are just working registers (clobbered).
*/
#if XCHAL_DCACHE_LINE_LOCKABLE
___unlock_dcache_all a2 a3
#endif
#if XCHAL_ICACHE_LINE_LOCKABLE
___unlock_icache_all a2 a3
#endif
___invalidate_dcache_all a2 a3
___invalidate_icache_all a2 a3
isync
initialize_cacheattr
#ifdef CONFIG_HAVE_SMP
movi a2, CCON # MX External Register to Configure Cache
movi a3, 1
wer a3, a2
#endif
/* Setup stack and enable window exceptions (keep irqs disabled) */
movi a1, start_info
l32i a1, a1, 0
/* Disable interrupts. */
/* Enable window exceptions if kernel is built with windowed ABI. */
movi a2, KERNEL_PS_WOE_MASK | LOCKLEVEL
wsr a2, ps
rsync
#ifdef CONFIG_SMP
/*
* Notice that we assume with SMP that cores have PRID
* supported by the cores.
*/
rsr a2, prid
bnez a2, .Lboot_secondary
#endif /* CONFIG_SMP */
/* Unpack data sections
*
* The linker script used to build the Linux kernel image
* creates a table located at __boot_reloc_table_start
* that contains the information what data needs to be unpacked.
*
* Uses a2-a7.
*/
movi a2, __boot_reloc_table_start
movi a3, __boot_reloc_table_end
1: beq a2, a3, 3f # no more entries?
l32i a4, a2, 0 # start destination (in RAM)
l32i a5, a2, 4 # end destination (in RAM)
l32i a6, a2, 8 # start source (in ROM)
addi a2, a2, 12 # next entry
beq a4, a5, 1b # skip, empty entry
beq a4, a6, 1b # skip, source and dest. are the same
2: l32i a7, a6, 0 # load word
addi a6, a6, 4
s32i a7, a4, 0 # store word
addi a4, a4, 4
bltu a4, a5, 2b
j 1b
3:
/* All code and initialized data segments have been copied.
* Now clear the BSS segment.
*/
movi a2, __bss_start # start of BSS
movi a3, __bss_stop # end of BSS
__loopt a2, a3, a4, 2
s32i a0, a2, 0
__endla a2, a3, 4
#if XCHAL_DCACHE_IS_WRITEBACK
/* After unpacking, flush the writeback cache to memory so the
* instructions/data are available.
*/
___flush_dcache_all a2 a3
#endif
memw
isync
___invalidate_icache_all a2 a3
isync
#ifdef CONFIG_XIP_KERNEL
/* Setup bootstrap CPU stack in XIP kernel */
movi a1, start_info
l32i a1, a1, 0
#endif
movi abi_arg0, 0
xsr abi_arg0, excsave1
/* init_arch kick-starts the linux kernel */
abi_call init_arch
abi_call start_kernel
should_never_return:
j should_never_return
#ifdef CONFIG_SMP
.Lboot_secondary:
movi a2, cpu_start_ccount
1:
memw
l32i a3, a2, 0
beqi a3, 0, 1b
movi a3, 0
s32i a3, a2, 0
1:
memw
l32i a3, a2, 0
beqi a3, 0, 1b
wsr a3, ccount
movi a3, 0
s32i a3, a2, 0
memw
movi abi_arg0, 0
wsr abi_arg0, excsave1
abi_call secondary_start_kernel
j should_never_return
#endif /* CONFIG_SMP */
ENDPROC(_startup)
#ifdef CONFIG_HOTPLUG_CPU
ENTRY(cpu_restart)
#if XCHAL_DCACHE_IS_WRITEBACK
___flush_invalidate_dcache_all a2 a3
#else
___invalidate_dcache_all a2 a3
#endif
memw
movi a2, CCON # MX External Register to Configure Cache
movi a3, 0
wer a3, a2
extw
rsr a0, prid
neg a2, a0
movi a3, cpu_start_id
memw
s32i a2, a3, 0
#if XCHAL_DCACHE_IS_WRITEBACK
dhwbi a3, 0
#endif
1:
memw
l32i a2, a3, 0
dhi a3, 0
bne a2, a0, 1b
/*
* Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
* Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
* xt-gdb to single step via DEBUG exceptions received directly
* by ocd.
*/
movi a1, 1
movi a0, 0
wsr a1, windowstart
wsr a0, windowbase
rsync
movi a1, LOCKLEVEL
wsr a1, ps
rsync
j _startup
ENDPROC(cpu_restart)
#endif /* CONFIG_HOTPLUG_CPU */
/*
* DATA section
*/
__REFDATA
.align 4
ENTRY(start_info)
.long init_thread_union + KERNEL_STACK_SIZE
/*
* BSS section
*/
__PAGE_ALIGNED_BSS
#ifdef CONFIG_MMU
ENTRY(swapper_pg_dir)
.fill PAGE_SIZE, 1, 0
END(swapper_pg_dir)
#endif