mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 00:28:54 +02:00
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>
384 lines
6.9 KiB
ArmAsm
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
|