ARM: P2V: eliminate head.S use of PHYS_OFFSET for !XIP_KERNEL
head.S makes use of PHYS_OFFSET. When it becomes a variable, the assembler won't understand this. Compute PHYS_OFFSET by the following method. This code is linked at its virtual address, but run at before the MMU is enabled, so at his physical address. 1: .long . .long PAGE_OFFSET adr r0, 1b @ r0 = physical ',' ldmia r0, {r1, r2} @ r1 = virtual '.', r2 = PAGE_OFFSET sub r1, r0, r1 @ r1 = physical-virtual add r2, r2, r1 @ r2 = PAGE_OFFSET + physical-virtual @ := PHYS_OFFSET. Switch XIP users of PHYS_OFFSET to use PLAT_PHYS_OFFSET - we can't use this method for XIP kernels as the code doesn't execute in RAM. Tested-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
b75c178afa
commit
72a20e22f4
1 changed files with 22 additions and 22 deletions
|
@ -26,14 +26,6 @@
|
||||||
#include <mach/debug-macro.S>
|
#include <mach/debug-macro.S>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (PHYS_OFFSET & 0x001fffff)
|
|
||||||
#error "PHYS_OFFSET must be at an even 2MiB boundary!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
|
|
||||||
#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* swapper_pg_dir is the virtual address of the initial page table.
|
* swapper_pg_dir is the virtual address of the initial page table.
|
||||||
* We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
|
* We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
|
||||||
|
@ -41,6 +33,7 @@
|
||||||
* the least significant 16 bits to be 0x8000, but we could probably
|
* the least significant 16 bits to be 0x8000, but we could probably
|
||||||
* relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
|
* relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
|
||||||
*/
|
*/
|
||||||
|
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
|
||||||
#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
|
#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
|
||||||
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
|
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,8 +41,8 @@
|
||||||
.globl swapper_pg_dir
|
.globl swapper_pg_dir
|
||||||
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
|
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
|
||||||
|
|
||||||
.macro pgtbl, rd
|
.macro pgtbl, rd, phys
|
||||||
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
|
add \rd, \phys, #TEXT_OFFSET - 0x4000
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#ifdef CONFIG_XIP_KERNEL
|
#ifdef CONFIG_XIP_KERNEL
|
||||||
|
@ -88,9 +81,18 @@ ENTRY(stext)
|
||||||
THUMB( it eq ) @ force fixup-able long branch encoding
|
THUMB( it eq ) @ force fixup-able long branch encoding
|
||||||
beq __error_p @ yes, error 'p'
|
beq __error_p @ yes, error 'p'
|
||||||
|
|
||||||
|
#ifndef CONFIG_XIP_KERNEL
|
||||||
|
adr r3, 2f
|
||||||
|
ldmia r3, {r4, r8}
|
||||||
|
sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
|
||||||
|
add r8, r8, r4 @ PHYS_OFFSET
|
||||||
|
#else
|
||||||
|
ldr r8, =PLAT_PHYS_OFFSET
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* r1 = machine no, r2 = atags,
|
* r1 = machine no, r2 = atags,
|
||||||
* r9 = cpuid, r10 = procinfo
|
* r8 = phys_offset, r9 = cpuid, r10 = procinfo
|
||||||
*/
|
*/
|
||||||
bl __vet_atags
|
bl __vet_atags
|
||||||
#ifdef CONFIG_SMP_ON_UP
|
#ifdef CONFIG_SMP_ON_UP
|
||||||
|
@ -114,21 +116,24 @@ ENTRY(stext)
|
||||||
1: b __enable_mmu
|
1: b __enable_mmu
|
||||||
ENDPROC(stext)
|
ENDPROC(stext)
|
||||||
.ltorg
|
.ltorg
|
||||||
|
#ifndef CONFIG_XIP_KERNEL
|
||||||
|
2: .long .
|
||||||
|
.long PAGE_OFFSET
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the initial page tables. We only setup the barest
|
* Setup the initial page tables. We only setup the barest
|
||||||
* amount which are required to get the kernel running, which
|
* amount which are required to get the kernel running, which
|
||||||
* generally means mapping in the kernel code.
|
* generally means mapping in the kernel code.
|
||||||
*
|
*
|
||||||
* r9 = cpuid
|
* r8 = phys_offset, r9 = cpuid, r10 = procinfo
|
||||||
* r10 = procinfo
|
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* r0, r3, r5-r7 corrupted
|
* r0, r3, r5-r7 corrupted
|
||||||
* r4 = physical page table address
|
* r4 = physical page table address
|
||||||
*/
|
*/
|
||||||
__create_page_tables:
|
__create_page_tables:
|
||||||
pgtbl r4 @ page table address
|
pgtbl r4, r8 @ page table address
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the 16K level 1 swapper page table
|
* Clear the 16K level 1 swapper page table
|
||||||
|
@ -184,10 +189,8 @@ __create_page_tables:
|
||||||
/*
|
/*
|
||||||
* Map some ram to cover our .data and .bss areas.
|
* Map some ram to cover our .data and .bss areas.
|
||||||
*/
|
*/
|
||||||
orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
|
add r3, r8, #TEXT_OFFSET
|
||||||
.if (KERNEL_RAM_PADDR & 0x00f00000)
|
orr r3, r3, r7
|
||||||
orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
|
|
||||||
.endif
|
|
||||||
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
|
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
|
||||||
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
|
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
|
||||||
ldr r6, =(_end - 1)
|
ldr r6, =(_end - 1)
|
||||||
|
@ -203,10 +206,7 @@ __create_page_tables:
|
||||||
* Then map first 1MB of ram in case it contains our boot params.
|
* Then map first 1MB of ram in case it contains our boot params.
|
||||||
*/
|
*/
|
||||||
add r0, r4, #PAGE_OFFSET >> 18
|
add r0, r4, #PAGE_OFFSET >> 18
|
||||||
orr r6, r7, #(PHYS_OFFSET & 0xff000000)
|
orr r6, r7, r8
|
||||||
.if (PHYS_OFFSET & 0x00f00000)
|
|
||||||
orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
|
|
||||||
.endif
|
|
||||||
str r6, [r0]
|
str r6, [r0]
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LL
|
#ifdef CONFIG_DEBUG_LL
|
||||||
|
|
Loading…
Reference in a new issue