aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head.S
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2011-02-21 00:53:35 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-10 11:43:45 -0500
commitb511d75d6150892e67c8ebfa9dc8eb37ebd02aa3 (patch)
tree0cec12cd64edeecac2b737f2788b012eab538285 /arch/arm/kernel/head.S
parent80f0aad77f3e1e9d9e518b09ac46963d628ae2be (diff)
ARM: 6747/1: P2V: Thumb2 support
Adding Thumb2 support to the runtime patching of the virt_to_phys and phys_to_virt opcodes. Tested both the 8-bit and the 16-bit fixups, using different placements in memory to exercize all code paths. Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> Reviewed-by: Dave Martin <dave.martin@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/head.S')
-rw-r--r--arch/arm/kernel/head.S49
1 files changed, 48 insertions, 1 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 591a2ead8ce..6a87261e1b1 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -461,7 +461,8 @@ __fixup_pv_table:
461 sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET 461 sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
462 add r4, r4, r3 @ adjust table start address 462 add r4, r4, r3 @ adjust table start address
463 add r5, r5, r3 @ adjust table end address 463 add r5, r5, r3 @ adjust table end address
464 str r8, [r7, r3]! @ save computed PHYS_OFFSET to __pv_phys_offset 464 add r7, r7, r3 @ adjust __pv_phys_offset address
465 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
465#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 466#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
466 mov r6, r3, lsr #24 @ constant for add/sub instructions 467 mov r6, r3, lsr #24 @ constant for add/sub instructions
467 teq r3, r6, lsl #24 @ must be 16MiB aligned 468 teq r3, r6, lsl #24 @ must be 16MiB aligned
@@ -469,6 +470,7 @@ __fixup_pv_table:
469 mov r6, r3, lsr #16 @ constant for add/sub instructions 470 mov r6, r3, lsr #16 @ constant for add/sub instructions
470 teq r3, r6, lsl #16 @ must be 64kiB aligned 471 teq r3, r6, lsl #16 @ must be 64kiB aligned
471#endif 472#endif
473THUMB( it ne @ cross section branch )
472 bne __error 474 bne __error
473 str r6, [r7, #4] @ save to __pv_offset 475 str r6, [r7, #4] @ save to __pv_offset
474 b __fixup_a_pv_table 476 b __fixup_a_pv_table
@@ -482,6 +484,50 @@ ENDPROC(__fixup_pv_table)
482 484
483 .text 485 .text
484__fixup_a_pv_table: 486__fixup_a_pv_table:
487#ifdef CONFIG_THUMB2_KERNEL
488#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
489 lsls r0, r6, #24
490 lsr r6, #8
491 beq 1f
492 clz r7, r0
493 lsr r0, #24
494 lsl r0, r7
495 bic r0, 0x0080
496 lsrs r7, #1
497 orrcs r0, #0x0080
498 orr r0, r0, r7, lsl #12
499#endif
5001: lsls r6, #24
501 beq 4f
502 clz r7, r6
503 lsr r6, #24
504 lsl r6, r7
505 bic r6, #0x0080
506 lsrs r7, #1
507 orrcs r6, #0x0080
508 orr r6, r6, r7, lsl #12
509 orr r6, #0x4000
510 b 4f
5112: @ at this point the C flag is always clear
512 add r7, r3
513#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
514 ldrh ip, [r7]
515 tst ip, 0x0400 @ the i bit tells us LS or MS byte
516 beq 3f
517 cmp r0, #0 @ set C flag, and ...
518 biceq ip, 0x0400 @ immediate zero value has a special encoding
519 streqh ip, [r7] @ that requires the i bit cleared
520#endif
5213: ldrh ip, [r7, #2]
522 and ip, 0x8f00
523 orrcc ip, r6 @ mask in offset bits 31-24
524 orrcs ip, r0 @ mask in offset bits 23-16
525 strh ip, [r7, #2]
5264: cmp r4, r5
527 ldrcc r7, [r4], #4 @ use branch for delay slot
528 bcc 2b
529 bx lr
530#else
485#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 531#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
486 and r0, r6, #255 @ offset bits 23-16 532 and r0, r6, #255 @ offset bits 23-16
487 mov r6, r6, lsr #8 @ offset bits 31-24 533 mov r6, r6, lsr #8 @ offset bits 31-24
@@ -499,6 +545,7 @@ __fixup_a_pv_table:
499 ldrcc r7, [r4], #4 @ use branch for delay slot 545 ldrcc r7, [r4], #4 @ use branch for delay slot
500 bcc 2b 546 bcc 2b
501 mov pc, lr 547 mov pc, lr
548#endif
502ENDPROC(__fixup_a_pv_table) 549ENDPROC(__fixup_a_pv_table)
503 550
504ENTRY(fixup_pv_table) 551ENTRY(fixup_pv_table)