diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 50 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 10 |
4 files changed, 37 insertions, 30 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ba412e02ec0c..123b7924904f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -218,7 +218,8 @@ config VECTORS_BASE | |||
218 | default DRAM_BASE if REMAP_VECTORS_TO_RAM | 218 | default DRAM_BASE if REMAP_VECTORS_TO_RAM |
219 | default 0x00000000 | 219 | default 0x00000000 |
220 | help | 220 | help |
221 | The base address of exception vectors. | 221 | The base address of exception vectors. This must be two pages |
222 | in size. | ||
222 | 223 | ||
223 | config ARM_PATCH_PHYS_VIRT | 224 | config ARM_PATCH_PHYS_VIRT |
224 | bool "Patch physical to virtual translations at runtime" if EMBEDDED | 225 | bool "Patch physical to virtual translations at runtime" if EMBEDDED |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 02437345289a..79a41fa978f5 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -944,9 +944,9 @@ __kuser_helper_end: | |||
944 | /* | 944 | /* |
945 | * Vector stubs. | 945 | * Vector stubs. |
946 | * | 946 | * |
947 | * This code is copied to 0xffff0200 so we can use branches in the | 947 | * This code is copied to 0xffff1000 so we can use branches in the |
948 | * vectors, rather than ldr's. Note that this code must not | 948 | * vectors, rather than ldr's. Note that this code must not exceed |
949 | * exceed 0x300 bytes. | 949 | * a page size. |
950 | * | 950 | * |
951 | * Common stub entry macro: | 951 | * Common stub entry macro: |
952 | * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC | 952 | * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC |
@@ -995,6 +995,15 @@ ENDPROC(vector_\name) | |||
995 | 995 | ||
996 | .globl __stubs_start | 996 | .globl __stubs_start |
997 | __stubs_start: | 997 | __stubs_start: |
998 | @ This must be the first word | ||
999 | .word vector_swi | ||
1000 | |||
1001 | vector_rst: | ||
1002 | ARM( swi SYS_ERROR0 ) | ||
1003 | THUMB( svc #0 ) | ||
1004 | THUMB( nop ) | ||
1005 | b vector_und | ||
1006 | |||
998 | /* | 1007 | /* |
999 | * Interrupt dispatcher | 1008 | * Interrupt dispatcher |
1000 | */ | 1009 | */ |
@@ -1089,6 +1098,16 @@ __stubs_start: | |||
1089 | .align 5 | 1098 | .align 5 |
1090 | 1099 | ||
1091 | /*============================================================================= | 1100 | /*============================================================================= |
1101 | * Address exception handler | ||
1102 | *----------------------------------------------------------------------------- | ||
1103 | * These aren't too critical. | ||
1104 | * (they're not supposed to happen, and won't happen in 32-bit data mode). | ||
1105 | */ | ||
1106 | |||
1107 | vector_addrexcptn: | ||
1108 | b vector_addrexcptn | ||
1109 | |||
1110 | /*============================================================================= | ||
1092 | * Undefined FIQs | 1111 | * Undefined FIQs |
1093 | *----------------------------------------------------------------------------- | 1112 | *----------------------------------------------------------------------------- |
1094 | * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC | 1113 | * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC |
@@ -1101,35 +1120,14 @@ __stubs_start: | |||
1101 | vector_fiq: | 1120 | vector_fiq: |
1102 | subs pc, lr, #4 | 1121 | subs pc, lr, #4 |
1103 | 1122 | ||
1104 | /*============================================================================= | ||
1105 | * Address exception handler | ||
1106 | *----------------------------------------------------------------------------- | ||
1107 | * These aren't too critical. | ||
1108 | * (they're not supposed to happen, and won't happen in 32-bit data mode). | ||
1109 | */ | ||
1110 | |||
1111 | vector_addrexcptn: | ||
1112 | b vector_addrexcptn | ||
1113 | |||
1114 | /* | ||
1115 | * We group all the following data together to optimise | ||
1116 | * for CPUs with separate I & D caches. | ||
1117 | */ | ||
1118 | .align 5 | ||
1119 | |||
1120 | .LCvswi: | ||
1121 | .word vector_swi | ||
1122 | |||
1123 | .globl __stubs_end | 1123 | .globl __stubs_end |
1124 | __stubs_end: | 1124 | __stubs_end: |
1125 | 1125 | ||
1126 | .equ stubs_offset, __vectors_start + 0x200 - __stubs_start | 1126 | .equ stubs_offset, __vectors_start + 0x1000 - __stubs_start |
1127 | 1127 | ||
1128 | .globl __vectors_start | 1128 | .globl __vectors_start |
1129 | __vectors_start: | 1129 | __vectors_start: |
1130 | ARM( swi SYS_ERROR0 ) | 1130 | W(b) vector_rst + stubs_offset |
1131 | THUMB( svc #0 ) | ||
1132 | THUMB( nop ) | ||
1133 | W(b) vector_und + stubs_offset | 1131 | W(b) vector_und + stubs_offset |
1134 | W(ldr) pc, .LCvswi + stubs_offset | 1132 | W(ldr) pc, .LCvswi + stubs_offset |
1135 | W(b) vector_pabt + stubs_offset | 1133 | W(b) vector_pabt + stubs_offset |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 9433e8a12b5e..2c8c7fa78b8c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -837,7 +837,7 @@ void __init early_trap_init(void *vectors_base) | |||
837 | * are visible to the instruction stream. | 837 | * are visible to the instruction stream. |
838 | */ | 838 | */ |
839 | memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); | 839 | memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); |
840 | memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); | 840 | memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); |
841 | memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); | 841 | memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); |
842 | 842 | ||
843 | /* | 843 | /* |
@@ -852,7 +852,7 @@ void __init early_trap_init(void *vectors_base) | |||
852 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), | 852 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), |
853 | sigreturn_codes, sizeof(sigreturn_codes)); | 853 | sigreturn_codes, sizeof(sigreturn_codes)); |
854 | 854 | ||
855 | flush_icache_range(vectors, vectors + PAGE_SIZE); | 855 | flush_icache_range(vectors, vectors + PAGE_SIZE * 2); |
856 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 856 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
857 | #else /* ifndef CONFIG_CPU_V7M */ | 857 | #else /* ifndef CONFIG_CPU_V7M */ |
858 | /* | 858 | /* |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4f56617a2392..9ea274d1af69 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -1160,7 +1160,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
1160 | /* | 1160 | /* |
1161 | * Allocate the vector page early. | 1161 | * Allocate the vector page early. |
1162 | */ | 1162 | */ |
1163 | vectors = early_alloc(PAGE_SIZE); | 1163 | vectors = early_alloc(PAGE_SIZE * 2); |
1164 | 1164 | ||
1165 | early_trap_init(vectors); | 1165 | early_trap_init(vectors); |
1166 | 1166 | ||
@@ -1210,10 +1210,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
1210 | 1210 | ||
1211 | if (!vectors_high()) { | 1211 | if (!vectors_high()) { |
1212 | map.virtual = 0; | 1212 | map.virtual = 0; |
1213 | map.length = PAGE_SIZE * 2; | ||
1213 | map.type = MT_LOW_VECTORS; | 1214 | map.type = MT_LOW_VECTORS; |
1214 | create_mapping(&map); | 1215 | create_mapping(&map); |
1215 | } | 1216 | } |
1216 | 1217 | ||
1218 | /* Now create a kernel read-only mapping */ | ||
1219 | map.pfn += 1; | ||
1220 | map.virtual = 0xffff0000 + PAGE_SIZE; | ||
1221 | map.length = PAGE_SIZE; | ||
1222 | map.type = MT_LOW_VECTORS; | ||
1223 | create_mapping(&map); | ||
1224 | |||
1217 | /* | 1225 | /* |
1218 | * Ask the machine support to map in the statically mapped devices. | 1226 | * Ask the machine support to map in the statically mapped devices. |
1219 | */ | 1227 | */ |