Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cada3c08 authored by Russell King's avatar Russell King
Browse files

ARM: P2V: extend to 16-bit translation offsets



MSM's memory is aligned to 2MB, which is more than we can do with our
existing method as we're limited to the upper 8 bits.  Extend this by
using two instructions to 16 bits, automatically selected when MSM is
enabled.

Acked-by: default avatarTony Lindgren <tony@atomide.com>
Reviewed-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
Tested-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent dc21af99
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -195,7 +195,6 @@ config ARM_PATCH_PHYS_VIRT
	bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)"
	depends on EXPERIMENTAL
	depends on !XIP_KERNEL && !THUMB2_KERNEL && MMU
	depends on !ARCH_MSM
	depends on !ARCH_REALVIEW || !SPARSEMEM
	help
	  Patch phys-to-virt translation functions at runtime according to
@@ -204,6 +203,10 @@ config ARM_PATCH_PHYS_VIRT
	  This can only be used with non-XIP, non-Thumb2, MMU kernels where
	  the base of physical memory is at a 16MB boundary.

config ARM_PATCH_PHYS_VIRT_16BIT
	def_bool y
	depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM

source "init/Kconfig"

source "kernel/Kconfig.freezer"
+17 −4
Original line number Diff line number Diff line
@@ -154,29 +154,42 @@
#ifndef __virt_to_phys
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT

/*
 * Constants used to force the right instruction encodings and shifts
 * so that all we need to do is modify the 8-bit constant field.
 */
#define __PV_BITS_31_24	0x81000000
#define __PV_BITS_23_16	0x00810000

extern unsigned long __pv_phys_offset;
#define PHYS_OFFSET __pv_phys_offset

#define __pv_stub(from,to,instr)			\
#define __pv_stub(from,to,instr,type)			\
	__asm__("@ __pv_stub\n"				\
	"1:	" instr "	%0, %1, %2\n"		\
	"	.pushsection .pv_table,\"a\"\n"		\
	"	.long	1b\n"				\
	"	.popsection\n"				\
	: "=r" (to)					\
	: "r" (from), "I" (0x81000000))
	: "r" (from), "I" (type))

static inline unsigned long __virt_to_phys(unsigned long x)
{
	unsigned long t;
	__pv_stub(x, t, "add");
	__pv_stub(x, t, "add", __PV_BITS_31_24);
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
	__pv_stub(t, t, "add", __PV_BITS_23_16);
#endif
	return t;
}

static inline unsigned long __phys_to_virt(unsigned long x)
{
	unsigned long t;
	__pv_stub(x, t, "sub");
	__pv_stub(x, t, "sub", __PV_BITS_31_24);
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
	__pv_stub(t, t, "sub", __PV_BITS_23_16);
#endif
	return t;
}
#else
+4 −0
Original line number Diff line number Diff line
@@ -31,7 +31,11 @@ struct mod_arch_specific {

/* Add __virt_to_phys patching state as well */
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
#else
#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
#endif
#else
#define MODULE_ARCH_VERMAGIC_P2V ""
#endif
+14 −1
Original line number Diff line number Diff line
@@ -456,8 +456,13 @@ __fixup_pv_table:
	add	r4, r4, r3	@ adjust table start address
	add	r5, r5, r3	@ adjust table end address
	str	r8, [r7, r3]!	@ save computed PHYS_OFFSET to __pv_phys_offset
#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
	mov	r6, r3, lsr #24	@ constant for add/sub instructions
	teq	r3, r6, lsl #24 @ must be 16MiB aligned
#else
	mov	r6, r3, lsr #16	@ constant for add/sub instructions
	teq	r3, r6, lsl #16	@ must be 64kiB aligned
#endif
	bne	__error
	str	r6, [r7, #4]	@ save to __pv_offset
	b	__fixup_a_pv_table
@@ -471,10 +476,18 @@ ENDPROC(__fixup_pv_table)

	.text
__fixup_a_pv_table:
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
	and	r0, r6, #255	@ offset bits 23-16
	mov	r6, r6, lsr #8	@ offset bits 31-24
#else
	mov	r0, #0		@ just in case...
#endif
	b	3f
2:	ldr	ip, [r7, r3]
	bic	ip, ip, #0x000000ff
	orr	ip, ip, r6
	tst	ip, #0x400	@ rotate shift tells us LS or MS byte
	orrne	ip, ip, r6	@ mask in offset bits 31-24
	orreq	ip, ip, r0	@ mask in offset bits 23-16
	str	ip, [r7, r3]
3:	cmp	r4, r5
	ldrcc	r7, [r4], #4	@ use branch for delay slot