aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/head.S')
-rw-r--r--arch/arm/kernel/head.S54
1 files changed, 15 insertions, 39 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index dd5d0f07d358..8d8748407cbe 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -34,52 +34,28 @@
34#define MACHINFO_PGOFFIO 12 34#define MACHINFO_PGOFFIO 12
35#define MACHINFO_NAME 16 35#define MACHINFO_NAME 16
36 36
37#ifndef CONFIG_XIP_KERNEL
38/* 37/*
39 * We place the page tables 16K below TEXTADDR. Therefore, we must make sure 38 * swapper_pg_dir is the virtual address of the initial page table.
40 * that TEXTADDR is correctly set. Currently, we expect the least significant 39 * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
41 * 16 bits to be 0x8000, but we could probably relax this restriction to 40 * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
42 * TEXTADDR >= PAGE_OFFSET + 0x4000 41 * the least significant 16 bits to be 0x8000, but we could probably
43 * 42 * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
44 * Note that swapper_pg_dir is the virtual address of the page tables, and
45 * pgtbl gives us a position-independent reference to these tables. We can
46 * do this because stext == TEXTADDR
47 */ 43 */
48#if (TEXTADDR & 0xffff) != 0x8000 44#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
49#error TEXTADDR must start at 0xXXXX8000 45#error KERNEL_RAM_ADDR must start at 0xXXXX8000
50#endif 46#endif
51 47
52 .globl swapper_pg_dir 48 .globl swapper_pg_dir
53 .equ swapper_pg_dir, TEXTADDR - 0x4000 49 .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
54 50
55 .macro pgtbl, rd, phys 51 .macro pgtbl, rd
56 adr \rd, stext 52 ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
57 sub \rd, \rd, #0x4000
58 .endm 53 .endm
59#else
60/*
61 * XIP Kernel:
62 *
63 * We place the page tables 16K below DATAADDR. Therefore, we must make sure
64 * that DATAADDR is correctly set. Currently, we expect the least significant
65 * 16 bits to be 0x8000, but we could probably relax this restriction to
66 * DATAADDR >= PAGE_OFFSET + 0x4000
67 *
68 * Note that pgtbl is meant to return the physical address of swapper_pg_dir.
69 * We can't make it relative to the kernel position in this case since
70 * the kernel can physically be anywhere.
71 */
72#if (DATAADDR & 0xffff) != 0x8000
73#error DATAADDR must start at 0xXXXX8000
74#endif
75
76 .globl swapper_pg_dir
77 .equ swapper_pg_dir, DATAADDR - 0x4000
78 54
79 .macro pgtbl, rd, phys 55#ifdef CONFIG_XIP_KERNEL
80 ldr \rd, =((DATAADDR - 0x4000) - PAGE_OFFSET) 56#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
81 add \rd, \rd, \phys 57#else
82 .endm 58#define TEXTADDR KERNEL_RAM_ADDR
83#endif 59#endif
84 60
85/* 61/*
@@ -280,7 +256,7 @@ __turn_mmu_on:
280 .type __create_page_tables, %function 256 .type __create_page_tables, %function
281__create_page_tables: 257__create_page_tables:
282 ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram 258 ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
283 pgtbl r4, r5 @ page table address 259 pgtbl r4 @ page table address
284 260
285 /* 261 /*
286 * Clear the 16K level 1 swapper page table 262 * Clear the 16K level 1 swapper page table