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

Commit 786f1b73 authored by Russell King's avatar Russell King
Browse files

ARM: hotplug cpu: ensure that __enable_mmu is identity mapped



__enable_mmu is required to be executed in an identity mapped region
to ensure that variances in CPUs do not cause a crash.  We currently
achieve this by assuming that it will be co-located with
__create_page_tables.  With hotplug CPU support, this assumption
becomes invalid.  Implement a better solution which ensures that
it will be appropriately mapped no matter where it is placed.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 80924ac5
Loading
Loading
Loading
Loading
+24 −9
Original line number Original line Diff line number Diff line
@@ -201,6 +201,7 @@ __turn_mmu_on:
	mov	r3, r3
	mov	r3, r3
	mov	r3, r13
	mov	r3, r13
	mov	pc, r3
	mov	pc, r3
__enable_mmu_end:
ENDPROC(__turn_mmu_on)
ENDPROC(__turn_mmu_on)




@@ -214,7 +215,7 @@ ENDPROC(__turn_mmu_on)
 * r10 = procinfo
 * r10 = procinfo
 *
 *
 * Returns:
 * Returns:
 *  r0, r3, r6, r7 corrupted
 *  r0, r3, r5-r7 corrupted
 *  r4 = physical page table address
 *  r4 = physical page table address
 */
 */
__create_page_tables:
__create_page_tables:
@@ -236,20 +237,30 @@ __create_page_tables:
	ldr	r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
	ldr	r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags


	/*
	/*
	 * Create identity mapping for first MB of kernel to
	 * Create identity mapping to cater for __enable_mmu.
	 * cater for the MMU enable.  This identity mapping
	 * This identity mapping will be removed by paging_init().
	 * will be removed by paging_init().  We use our current program
	 * counter to determine corresponding section base address.
	 */
	 */
	mov	r6, pc
	adr	r0, __enable_mmu_loc
	mov	r6, r6, lsr #20			@ start of kernel section
	ldmia	r0, {r3, r5, r6}
	orr	r3, r7, r6, lsl #20		@ flags + kernel base
	sub	r0, r0, r3			@ virt->phys offset
	str	r3, [r4, r6, lsl #2]		@ identity mapping
	add	r5, r5, r0			@ phys __enable_mmu
	add	r6, r6, r0			@ phys __enable_mmu_end
	mov	r5, r5, lsr #20
	mov	r6, r6, lsr #20

1:	orr	r3, r7, r5, lsl #20		@ flags + kernel base
	str	r3, [r4, r5, lsl #2]		@ identity mapping
	teq	r5, r6
	addne	r5, r5, #1			@ next section
	bne	1b


	/*
	/*
	 * Now setup the pagetables for our kernel direct
	 * Now setup the pagetables for our kernel direct
	 * mapped region.
	 * mapped region.
	 */
	 */
	mov	r3, pc
	mov	r3, r3, lsr #20
	orr	r3, r7, r3, lsl #20
	add	r0, r4,  #(KERNEL_START & 0xff000000) >> 18
	add	r0, r4,  #(KERNEL_START & 0xff000000) >> 18
	str	r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
	str	r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
	ldr	r6, =(KERNEL_END - 1)
	ldr	r6, =(KERNEL_END - 1)
@@ -333,5 +344,9 @@ __create_page_tables:
	mov	pc, lr
	mov	pc, lr
ENDPROC(__create_page_tables)
ENDPROC(__create_page_tables)
	.ltorg
	.ltorg
__enable_mmu_loc:
	.long	.
	.long	__enable_mmu
	.long	__enable_mmu_end


#include "head-common.S"
#include "head-common.S"