aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mm/proc-arm6_7.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/proc-arm6_7.S')
-rw-r--r--arch/arm/mm/proc-arm6_7.S256
1 files changed, 76 insertions, 180 deletions
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 5f79dc4ce3f..e5b974cddac 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -29,19 +29,19 @@ ENTRY(cpu_arm7_dcache_clean_area)
/*
* Function: arm6_7_data_abort ()
*
- * Params : r2 = address of aborted instruction
- * : sp = pointer to registers
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
*
* Purpose : obtain information about current aborted instruction
*
- * Returns : r0 = address of abort
- * : r1 = FSR
+ * Returns : r4-r5, r10-r11, r13 preserved
*/
ENTRY(cpu_arm7_data_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
- ldr r8, [r2] @ read arm instruction
+ ldr r8, [r4] @ read arm instruction
tst r8, #1 << 20 @ L = 0 -> write?
orreq r1, r1, #1 << 11 @ yes.
and r7, r8, #15 << 24
@@ -49,7 +49,7 @@ ENTRY(cpu_arm7_data_abort)
nop
/* 0 */ b .data_unknown
-/* 1 */ mov pc, lr @ swp
+/* 1 */ b do_DataAbort @ swp
/* 2 */ b .data_unknown
/* 3 */ b .data_unknown
/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
@@ -60,87 +60,85 @@ ENTRY(cpu_arm7_data_abort)
/* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
/* a */ b .data_unknown
/* b */ b .data_unknown
-/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
-/* d */ mov pc, lr @ ldc rd, [rn, #m]
+/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+/* d */ b do_DataAbort @ ldc rd, [rn, #m]
/* e */ b .data_unknown
/* f */
.data_unknown: @ Part of jumptable
- mov r0, r2
+ mov r0, r4
mov r1, r8
- mov r2, sp
- bl baddataabort
- b ret_from_exception
+ b baddataabort
ENTRY(cpu_arm6_data_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
- ldr r8, [r2] @ read arm instruction
+ ldr r8, [r4] @ read arm instruction
tst r8, #1 << 20 @ L = 0 -> write?
orreq r1, r1, #1 << 11 @ yes.
and r7, r8, #14 << 24
teq r7, #8 << 24 @ was it ldm/stm
- movne pc, lr
+ bne do_DataAbort
.data_arm_ldmstm:
tst r8, #1 << 21 @ check writeback bit
- moveq pc, lr @ no writeback -> no fixup
+ beq do_DataAbort @ no writeback -> no fixup
mov r7, #0x11
orr r7, r7, #0x1100
and r6, r8, r7
- and r2, r8, r7, lsl #1
- add r6, r6, r2, lsr #1
- and r2, r8, r7, lsl #2
- add r6, r6, r2, lsr #2
- and r2, r8, r7, lsl #3
- add r6, r6, r2, lsr #3
+ and r9, r8, r7, lsl #1
+ add r6, r6, r9, lsr #1
+ and r9, r8, r7, lsl #2
+ add r6, r6, r9, lsr #2
+ and r9, r8, r7, lsl #3
+ add r6, r6, r9, lsr #3
add r6, r6, r6, lsr #8
add r6, r6, r6, lsr #4
and r6, r6, #15 @ r6 = no. of registers to transfer.
- and r5, r8, #15 << 16 @ Extract 'n' from instruction
- ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ and r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
tst r8, #1 << 23 @ Check U bit
subne r7, r7, r6, lsl #2 @ Undo increment
addeq r7, r7, r6, lsl #2 @ Undo decrement
- str r7, [sp, r5, lsr #14] @ Put register 'Rn'
- mov pc, lr
+ str r7, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
.data_arm_apply_r6_and_rn:
- and r5, r8, #15 << 16 @ Extract 'n' from instruction
- ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ and r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
tst r8, #1 << 23 @ Check U bit
subne r7, r7, r6 @ Undo incrmenet
addeq r7, r7, r6 @ Undo decrement
- str r7, [sp, r5, lsr #14] @ Put register 'Rn'
- mov pc, lr
+ str r7, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
.data_arm_lateldrpreconst:
tst r8, #1 << 21 @ check writeback bit
- moveq pc, lr @ no writeback -> no fixup
+ beq do_DataAbort @ no writeback -> no fixup
.data_arm_lateldrpostconst:
- movs r2, r8, lsl #20 @ Get offset
- moveq pc, lr @ zero -> no fixup
- and r5, r8, #15 << 16 @ Extract 'n' from instruction
- ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ movs r6, r8, lsl #20 @ Get offset
+ beq do_DataAbort @ zero -> no fixup
+ and r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
tst r8, #1 << 23 @ Check U bit
- subne r7, r7, r2, lsr #20 @ Undo increment
- addeq r7, r7, r2, lsr #20 @ Undo decrement
- str r7, [sp, r5, lsr #14] @ Put register 'Rn'
- mov pc, lr
+ subne r7, r7, r6, lsr #20 @ Undo increment
+ addeq r7, r7, r6, lsr #20 @ Undo decrement
+ str r7, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
.data_arm_lateldrprereg:
tst r8, #1 << 21 @ check writeback bit
- moveq pc, lr @ no writeback -> no fixup
+ beq do_DataAbort @ no writeback -> no fixup
.data_arm_lateldrpostreg:
and r7, r8, #15 @ Extract 'm' from instruction
- ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
- mov r5, r8, lsr #7 @ get shift count
- ands r5, r5, #31
+ ldr r6, [r2, r7, lsl #2] @ Get register 'Rm'
+ mov r9, r8, lsr #7 @ get shift count
+ ands r9, r9, #31
and r7, r8, #0x70 @ get shift type
orreq r7, r7, #8 @ shift count = 0
add pc, pc, r7
nop
- mov r6, r6, lsl r5 @ 0: LSL #!0
+ mov r6, r6, lsl r9 @ 0: LSL #!0
b .data_arm_apply_r6_and_rn
b .data_arm_apply_r6_and_rn @ 1: LSL #0
nop
@@ -148,7 +146,7 @@ ENTRY(cpu_arm6_data_abort)
nop
b .data_unknown @ 3: MUL?
nop
- mov r6, r6, lsr r5 @ 4: LSR #!0
+ mov r6, r6, lsr r9 @ 4: LSR #!0
b .data_arm_apply_r6_and_rn
mov r6, r6, lsr #32 @ 5: LSR #32
b .data_arm_apply_r6_and_rn
@@ -156,7 +154,7 @@ ENTRY(cpu_arm6_data_abort)
nop
b .data_unknown @ 7: MUL?
nop
- mov r6, r6, asr r5 @ 8: ASR #!0
+ mov r6, r6, asr r9 @ 8: ASR #!0
b .data_arm_apply_r6_and_rn
mov r6, r6, asr #32 @ 9: ASR #32
b .data_arm_apply_r6_and_rn
@@ -164,7 +162,7 @@ ENTRY(cpu_arm6_data_abort)
nop
b .data_unknown @ B: MUL?
nop
- mov r6, r6, ror r5 @ C: ROR #!0
+ mov r6, r6, ror r9 @ C: ROR #!0
b .data_arm_apply_r6_and_rn
mov r6, r6, rrx @ D: RRX
b .data_arm_apply_r6_and_rn
@@ -269,159 +267,57 @@ __arm7_setup: mov r0, #0
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm6_processor_functions, #object
-ENTRY(arm6_processor_functions)
- .word cpu_arm6_data_abort
- .word legacy_pabort
- .word cpu_arm6_proc_init
- .word cpu_arm6_proc_fin
- .word cpu_arm6_reset
- .word cpu_arm6_do_idle
- .word cpu_arm6_dcache_clean_area
- .word cpu_arm6_switch_mm
- .word cpu_arm6_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm6_processor_functions, . - arm6_processor_functions
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm7_processor_functions, #object
-ENTRY(arm7_processor_functions)
- .word cpu_arm7_data_abort
- .word legacy_pabort
- .word cpu_arm7_proc_init
- .word cpu_arm7_proc_fin
- .word cpu_arm7_reset
- .word cpu_arm7_do_idle
- .word cpu_arm7_dcache_clean_area
- .word cpu_arm7_switch_mm
- .word cpu_arm7_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm7_processor_functions, . - arm7_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm6, dabort=cpu_arm6_data_abort, pabort=legacy_pabort
+ define_processor_functions arm7, dabort=cpu_arm7_data_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv3"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v3"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm6_name, #object
-cpu_arm6_name: .asciz "ARM6"
- .size cpu_arm6_name, . - cpu_arm6_name
-
- .type cpu_arm610_name, #object
-cpu_arm610_name:
- .asciz "ARM610"
- .size cpu_arm610_name, . - cpu_arm610_name
-
- .type cpu_arm7_name, #object
-cpu_arm7_name: .asciz "ARM7"
- .size cpu_arm7_name, . - cpu_arm7_name
-
- .type cpu_arm710_name, #object
-cpu_arm710_name:
- .asciz "ARM710"
- .size cpu_arm710_name, . - cpu_arm710_name
+ string cpu_arch_name, "armv3"
+ string cpu_elf_name, "v3"
+ string cpu_arm6_name, "ARM6"
+ string cpu_arm610_name, "ARM610"
+ string cpu_arm7_name, "ARM7"
+ string cpu_arm710_name, "ARM710"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm6_proc_info, #object
-__arm6_proc_info:
- .long 0x41560600
- .long 0xfffffff0
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm6_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm6_name
- .long arm6_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm6_proc_info, . - __arm6_proc_info
-
- .type __arm610_proc_info, #object
-__arm610_proc_info:
- .long 0x41560610
- .long 0xfffffff0
- .long 0x00000c1e
+.macro arm67_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ cpu_mm_mmu_flags:req, cpu_flush:req, cpu_proc_funcs:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long \cpu_mm_mmu_flags
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __arm6_setup
+ b \cpu_flush
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm610_name
- .long arm6_processor_functions
+ .long \cpu_name
+ .long \cpu_proc_funcs
.long v3_tlb_fns
.long v3_user_fns
.long v3_cache_fns
- .size __arm610_proc_info, . - __arm610_proc_info
-
- .type __arm7_proc_info, #object
-__arm7_proc_info:
- .long 0x41007000
- .long 0xffffff00
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm7_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm7_proc_info, . - __arm7_proc_info
-
- .type __arm710_proc_info, #object
-__arm710_proc_info:
- .long 0x41007100
- .long 0xfff8ff00
- .long PMD_TYPE_SECT | \
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm67_proc_info arm6, 0x41560600, 0xfffffff0, cpu_arm6_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm610, 0x41560610, 0xfffffff0, cpu_arm610_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm7, 0x41007000, 0xffffff00, cpu_arm7_name, \
+ 0x00000c1e, __arm7_setup, arm7_processor_functions
+ arm67_proc_info arm710, 0x41007100, 0xfff8ff00, cpu_arm710_name, \
+ PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm710_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm710_proc_info, . - __arm710_proc_info
+ PMD_SECT_AP_READ, \
+ __arm7_setup, arm7_processor_functions