arch/arm/kernel/phys2virt.S

Source file repositories/reference/linux-study-clean/arch/arm/kernel/phys2virt.S

File Facts

System
Linux kernel
Corpus path
arch/arm/kernel/phys2virt.S
Extension
.S
Size
7924 bytes
Lines
239
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: arch/arm
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/page.h>

#ifdef __ARMEB__
#define LOW_OFFSET	0x4
#define HIGH_OFFSET	0x0
#else
#define LOW_OFFSET	0x0
#define HIGH_OFFSET	0x4
#endif

/*
 * __fixup_pv_table - patch the stub instructions with the delta between
 *                    PHYS_OFFSET and PAGE_OFFSET, which is assumed to be
 *                    2 MiB aligned.
 *
 * Called from head.S, which expects the following registers to be preserved:
 *   r1 = machine no, r2 = atags or dtb,
 *   r8 = phys_offset, r9 = cpuid, r10 = procinfo
 */
	__HEAD
ENTRY(__fixup_pv_table)
	mov	r0, r8, lsr #PAGE_SHIFT	@ convert to PFN
	str_l	r0, __pv_phys_pfn_offset, r3

	adr_l	r0, __pv_offset
	subs	r3, r8, #PAGE_OFFSET	@ PHYS_OFFSET - PAGE_OFFSET
	mvn	ip, #0
	strcc	ip, [r0, #HIGH_OFFSET]	@ save to __pv_offset high bits
	str	r3, [r0, #LOW_OFFSET]	@ save to __pv_offset low bits

	mov	r0, r3, lsr #21		@ constant for add/sub instructions
	teq	r3, r0, lsl #21 	@ must be 2 MiB aligned
	bne	0f

	adr_l	r4, __pv_table_begin
	adr_l	r5, __pv_table_end
	b	__fixup_a_pv_table

0:	mov	r0, r0			@ deadloop on error
	b	0b
ENDPROC(__fixup_pv_table)

	.text
__fixup_a_pv_table:
	adr_l	r6, __pv_offset
	ldr	r0, [r6, #HIGH_OFFSET]	@ pv_offset high word
	ldr	r6, [r6, #LOW_OFFSET]	@ pv_offset low word
	cmn	r0, #1
#ifdef CONFIG_THUMB2_KERNEL
	@
	@ The Thumb-2 versions of the patchable sequences are
	@
	@ phys-to-virt:			movw	<reg>, #offset<31:21>
	@				lsl	<reg>, #21
	@				sub	<VA>, <PA>, <reg>
	@
	@ virt-to-phys (non-LPAE):	movw	<reg>, #offset<31:21>
	@				lsl	<reg>, #21
	@				add	<PA>, <VA>, <reg>
	@
	@ virt-to-phys (LPAE):		movw	<reg>, #offset<31:21>
	@				lsl	<reg>, #21
	@				adds	<PAlo>, <VA>, <reg>
	@				mov	<PAhi>, #offset<39:32>
	@				adc	<PAhi>, <PAhi>, #0
	@
	@ In the non-LPAE case, all patchable instructions are MOVW

Annotation

Implementation Notes