diff options
| -rw-r--r-- | arch/arm/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/boot/compressed/head.S | 26 | ||||
| -rw-r--r-- | arch/arm/include/asm/cacheflush.h | 8 | ||||
| -rw-r--r-- | arch/arm/include/asm/page.h | 8 | ||||
| -rw-r--r-- | arch/arm/include/asm/proc-fns.h | 8 | ||||
| -rw-r--r-- | arch/arm/include/asm/system.h | 6 | ||||
| -rw-r--r-- | arch/arm/include/asm/tlbflush.h | 19 | ||||
| -rw-r--r-- | arch/arm/mm/Kconfig | 35 | ||||
| -rw-r--r-- | arch/arm/mm/Makefile | 4 | ||||
| -rw-r--r-- | arch/arm/mm/cache-fa.S | 220 | ||||
| -rw-r--r-- | arch/arm/mm/copypage-fa.c | 86 | ||||
| -rw-r--r-- | arch/arm/mm/proc-fa526.S | 248 | ||||
| -rw-r--r-- | arch/arm/mm/tlb-fa.S | 75 |
13 files changed, 742 insertions, 2 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 24e0f0187697..d29f9260fb1c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
| @@ -72,6 +72,7 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi | |||
| 72 | tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi | 72 | tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi |
| 73 | tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi | 73 | tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi |
| 74 | tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi | 74 | tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi |
| 75 | tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi | ||
| 75 | tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 | 76 | tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 |
| 76 | tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 | 77 | tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 |
| 77 | tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale | 78 | tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 77d614232d81..def02483286a 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
| @@ -459,6 +459,20 @@ __armv7_mmu_cache_on: | |||
| 459 | mcr p15, 0, r0, c7, c5, 4 @ ISB | 459 | mcr p15, 0, r0, c7, c5, 4 @ ISB |
| 460 | mov pc, r12 | 460 | mov pc, r12 |
| 461 | 461 | ||
| 462 | __fa526_cache_on: | ||
| 463 | mov r12, lr | ||
| 464 | bl __setup_mmu | ||
| 465 | mov r0, #0 | ||
| 466 | mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache | ||
| 467 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 468 | mcr p15, 0, r0, c8, c7, 0 @ flush UTLB | ||
| 469 | mrc p15, 0, r0, c1, c0, 0 @ read control reg | ||
| 470 | orr r0, r0, #0x1000 @ I-cache enable | ||
| 471 | bl __common_mmu_cache_on | ||
| 472 | mov r0, #0 | ||
| 473 | mcr p15, 0, r0, c8, c7, 0 @ flush UTLB | ||
| 474 | mov pc, r12 | ||
| 475 | |||
| 462 | __arm6_mmu_cache_on: | 476 | __arm6_mmu_cache_on: |
| 463 | mov r12, lr | 477 | mov r12, lr |
| 464 | bl __setup_mmu | 478 | bl __setup_mmu |
| @@ -636,6 +650,12 @@ proc_types: | |||
| 636 | b __armv4_mmu_cache_off | 650 | b __armv4_mmu_cache_off |
| 637 | b __armv5tej_mmu_cache_flush | 651 | b __armv5tej_mmu_cache_flush |
| 638 | 652 | ||
| 653 | .word 0x66015261 @ FA526 | ||
| 654 | .word 0xff01fff1 | ||
| 655 | b __fa526_cache_on | ||
| 656 | b __armv4_mmu_cache_off | ||
| 657 | b __fa526_cache_flush | ||
| 658 | |||
| 639 | @ These match on the architecture ID | 659 | @ These match on the architecture ID |
| 640 | 660 | ||
| 641 | .word 0x00020000 @ ARMv4T | 661 | .word 0x00020000 @ ARMv4T |
| @@ -775,6 +795,12 @@ __armv4_mpu_cache_flush: | |||
| 775 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | 795 | mcr p15, 0, ip, c7, c10, 4 @ drain WB |
| 776 | mov pc, lr | 796 | mov pc, lr |
| 777 | 797 | ||
| 798 | __fa526_cache_flush: | ||
| 799 | mov r1, #0 | ||
| 800 | mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache | ||
| 801 | mcr p15, 0, r1, c7, c5, 0 @ flush I cache | ||
| 802 | mcr p15, 0, r1, c7, c10, 4 @ drain WB | ||
| 803 | mov pc, lr | ||
| 778 | 804 | ||
| 779 | __armv6_mmu_cache_flush: | 805 | __armv6_mmu_cache_flush: |
| 780 | mov r1, #0 | 806 | mov r1, #0 |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 6cbd8fdc9f1f..a6b8b90ed57f 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
| @@ -46,6 +46,14 @@ | |||
| 46 | # define MULTI_CACHE 1 | 46 | # define MULTI_CACHE 1 |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #if defined(CONFIG_CPU_FA526) | ||
| 50 | # ifdef _CACHE | ||
| 51 | # define MULTI_CACHE 1 | ||
| 52 | # else | ||
| 53 | # define _CACHE fa | ||
| 54 | # endif | ||
| 55 | #endif | ||
| 56 | |||
| 49 | #if defined(CONFIG_CPU_ARM926T) | 57 | #if defined(CONFIG_CPU_ARM926T) |
| 50 | # ifdef _CACHE | 58 | # ifdef _CACHE |
| 51 | # define MULTI_CACHE 1 | 59 | # define MULTI_CACHE 1 |
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index f341c9dbd662..e6eb8a67b807 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h | |||
| @@ -76,6 +76,14 @@ | |||
| 76 | # endif | 76 | # endif |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
| 79 | #ifdef CONFIG_CPU_COPY_FA | ||
| 80 | # ifdef _USER | ||
| 81 | # define MULTI_USER 1 | ||
| 82 | # else | ||
| 83 | # define _USER fa | ||
| 84 | # endif | ||
| 85 | #endif | ||
| 86 | |||
| 79 | #ifdef CONFIG_CPU_SA1100 | 87 | #ifdef CONFIG_CPU_SA1100 |
| 80 | # ifdef _USER | 88 | # ifdef _USER |
| 81 | # define MULTI_USER 1 | 89 | # define MULTI_USER 1 |
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index db80203b68e0..00949281d3ee 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h | |||
| @@ -89,6 +89,14 @@ | |||
| 89 | # define CPU_NAME cpu_arm922 | 89 | # define CPU_NAME cpu_arm922 |
| 90 | # endif | 90 | # endif |
| 91 | # endif | 91 | # endif |
| 92 | # ifdef CONFIG_CPU_FA526 | ||
| 93 | # ifdef CPU_NAME | ||
| 94 | # undef MULTI_CPU | ||
| 95 | # define MULTI_CPU | ||
| 96 | # else | ||
| 97 | # define CPU_NAME cpu_fa526 | ||
| 98 | # endif | ||
| 99 | # endif | ||
| 92 | # ifdef CONFIG_CPU_ARM925T | 100 | # ifdef CONFIG_CPU_ARM925T |
| 93 | # ifdef CPU_NAME | 101 | # ifdef CPU_NAME |
| 94 | # undef MULTI_CPU | 102 | # undef MULTI_CPU |
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 811be55f338e..d6a4dad99c9b 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
| @@ -125,6 +125,12 @@ extern unsigned int user_debug; | |||
| 125 | : : "r" (0) : "memory") | 125 | : : "r" (0) : "memory") |
| 126 | #define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ | 126 | #define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ |
| 127 | : : "r" (0) : "memory") | 127 | : : "r" (0) : "memory") |
| 128 | #elif defined(CONFIG_CPU_FA526) | ||
| 129 | #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | ||
| 130 | : : "r" (0) : "memory") | ||
| 131 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | ||
| 132 | : : "r" (0) : "memory") | ||
| 133 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | ||
| 128 | #else | 134 | #else |
| 129 | #define isb() __asm__ __volatile__ ("" : : : "memory") | 135 | #define isb() __asm__ __volatile__ ("" : : : "memory") |
| 130 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 136 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index ffedd2494eab..a62218013c78 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction | 54 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction |
| 55 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction | 55 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction |
| 56 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) | 56 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) |
| 57 | * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB)) | ||
| 57 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction | 58 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction |
| 58 | * v7wbi - identical to v6wbi | 59 | * v7wbi - identical to v6wbi |
| 59 | */ | 60 | */ |
| @@ -90,6 +91,22 @@ | |||
| 90 | # define v4_always_flags (-1UL) | 91 | # define v4_always_flags (-1UL) |
| 91 | #endif | 92 | #endif |
| 92 | 93 | ||
| 94 | #define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \ | ||
| 95 | TLB_V4_U_FULL | TLB_V4_U_PAGE) | ||
| 96 | |||
| 97 | #ifdef CONFIG_CPU_TLB_FA | ||
| 98 | # define fa_possible_flags fa_tlb_flags | ||
| 99 | # define fa_always_flags fa_tlb_flags | ||
| 100 | # ifdef _TLB | ||
| 101 | # define MULTI_TLB 1 | ||
| 102 | # else | ||
| 103 | # define _TLB fa | ||
| 104 | # endif | ||
| 105 | #else | ||
| 106 | # define fa_possible_flags 0 | ||
| 107 | # define fa_always_flags (-1UL) | ||
| 108 | #endif | ||
| 109 | |||
| 93 | #define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ | 110 | #define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ |
| 94 | TLB_V4_I_FULL | TLB_V4_D_FULL | \ | 111 | TLB_V4_I_FULL | TLB_V4_D_FULL | \ |
| 95 | TLB_V4_I_PAGE | TLB_V4_D_PAGE) | 112 | TLB_V4_I_PAGE | TLB_V4_D_PAGE) |
| @@ -268,6 +285,7 @@ extern struct cpu_tlb_fns cpu_tlb; | |||
| 268 | v4wbi_possible_flags | \ | 285 | v4wbi_possible_flags | \ |
| 269 | fr_possible_flags | \ | 286 | fr_possible_flags | \ |
| 270 | v4wb_possible_flags | \ | 287 | v4wb_possible_flags | \ |
| 288 | fa_possible_flags | \ | ||
| 271 | v6wbi_possible_flags | \ | 289 | v6wbi_possible_flags | \ |
| 272 | v7wbi_possible_flags) | 290 | v7wbi_possible_flags) |
| 273 | 291 | ||
| @@ -276,6 +294,7 @@ extern struct cpu_tlb_fns cpu_tlb; | |||
| 276 | v4wbi_always_flags & \ | 294 | v4wbi_always_flags & \ |
| 277 | fr_always_flags & \ | 295 | fr_always_flags & \ |
| 278 | v4wb_always_flags & \ | 296 | v4wb_always_flags & \ |
| 297 | fa_always_flags & \ | ||
| 279 | v6wbi_always_flags & \ | 298 | v6wbi_always_flags & \ |
| 280 | v7wbi_always_flags) | 299 | v7wbi_always_flags) |
| 281 | 300 | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index d490f3773c01..bc3331863d9d 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -186,6 +186,24 @@ config CPU_ARM926T | |||
| 186 | Say Y if you want support for the ARM926T processor. | 186 | Say Y if you want support for the ARM926T processor. |
| 187 | Otherwise, say N. | 187 | Otherwise, say N. |
| 188 | 188 | ||
| 189 | # FA526 | ||
| 190 | config CPU_FA526 | ||
| 191 | bool | ||
| 192 | select CPU_32v4 | ||
| 193 | select CPU_ABRT_EV4 | ||
| 194 | select CPU_PABRT_NOIFAR | ||
| 195 | select CPU_CACHE_VIVT | ||
| 196 | select CPU_CP15_MMU | ||
| 197 | select CPU_CACHE_FA | ||
| 198 | select CPU_COPY_FA if MMU | ||
| 199 | select CPU_TLB_FA if MMU | ||
| 200 | help | ||
| 201 | The FA526 is a version of the ARMv4 compatible processor with | ||
| 202 | Branch Target Buffer, Unified TLB and cache line size 16. | ||
| 203 | |||
| 204 | Say Y if you want support for the FA526 processor. | ||
| 205 | Otherwise, say N. | ||
| 206 | |||
| 189 | # ARM940T | 207 | # ARM940T |
| 190 | config CPU_ARM940T | 208 | config CPU_ARM940T |
| 191 | bool "Support ARM940T processor" if ARCH_INTEGRATOR | 209 | bool "Support ARM940T processor" if ARCH_INTEGRATOR |
| @@ -484,6 +502,9 @@ config CPU_CACHE_VIVT | |||
| 484 | config CPU_CACHE_VIPT | 502 | config CPU_CACHE_VIPT |
| 485 | bool | 503 | bool |
| 486 | 504 | ||
| 505 | config CPU_CACHE_FA | ||
| 506 | bool | ||
| 507 | |||
| 487 | if MMU | 508 | if MMU |
| 488 | # The copy-page model | 509 | # The copy-page model |
| 489 | config CPU_COPY_V3 | 510 | config CPU_COPY_V3 |
| @@ -498,6 +519,9 @@ config CPU_COPY_V4WB | |||
| 498 | config CPU_COPY_FEROCEON | 519 | config CPU_COPY_FEROCEON |
| 499 | bool | 520 | bool |
| 500 | 521 | ||
| 522 | config CPU_COPY_FA | ||
| 523 | bool | ||
| 524 | |||
| 501 | config CPU_COPY_V6 | 525 | config CPU_COPY_V6 |
| 502 | bool | 526 | bool |
| 503 | 527 | ||
| @@ -528,6 +552,13 @@ config CPU_TLB_FEROCEON | |||
| 528 | help | 552 | help |
| 529 | Feroceon TLB (v4wbi with non-outer-cachable page table walks). | 553 | Feroceon TLB (v4wbi with non-outer-cachable page table walks). |
| 530 | 554 | ||
| 555 | config CPU_TLB_FA | ||
| 556 | bool | ||
| 557 | help | ||
| 558 | Faraday ARM FA526 architecture, unified TLB with writeback cache | ||
| 559 | and invalidate instruction cache entry. Branch target buffer is | ||
| 560 | also supported. | ||
| 561 | |||
| 531 | config CPU_TLB_V6 | 562 | config CPU_TLB_V6 |
| 532 | bool | 563 | bool |
| 533 | 564 | ||
| @@ -638,7 +669,7 @@ config CPU_DCACHE_SIZE | |||
| 638 | 669 | ||
| 639 | config CPU_DCACHE_WRITETHROUGH | 670 | config CPU_DCACHE_WRITETHROUGH |
| 640 | bool "Force write through D-cache" | 671 | bool "Force write through D-cache" |
| 641 | depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE | 672 | depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE |
| 642 | default y if CPU_ARM925T | 673 | default y if CPU_ARM925T |
| 643 | help | 674 | help |
| 644 | Say Y here to use the data cache in writethrough mode. Unless you | 675 | Say Y here to use the data cache in writethrough mode. Unless you |
| @@ -653,7 +684,7 @@ config CPU_CACHE_ROUND_ROBIN | |||
| 653 | 684 | ||
| 654 | config CPU_BPREDICT_DISABLE | 685 | config CPU_BPREDICT_DISABLE |
| 655 | bool "Disable branch prediction" | 686 | bool "Disable branch prediction" |
| 656 | depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 | 687 | depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 || CPU_FA526 |
| 657 | help | 688 | help |
| 658 | Say Y here to disable branch prediction. If unsure, say N. | 689 | Say Y here to disable branch prediction. If unsure, say N. |
| 659 | 690 | ||
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 480f78a3611a..40f941c2245c 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
| @@ -32,6 +32,7 @@ obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o | |||
| 32 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o | 32 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o |
| 33 | obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o | 33 | obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o |
| 34 | obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o | 34 | obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o |
| 35 | obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o | ||
| 35 | 36 | ||
| 36 | obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o | 37 | obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o |
| 37 | obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o | 38 | obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o |
| @@ -41,6 +42,7 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o | |||
| 41 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o | 42 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o |
| 42 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o | 43 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o |
| 43 | obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o | 44 | obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o |
| 45 | obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o | ||
| 44 | 46 | ||
| 45 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o | 47 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o |
| 46 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o | 48 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o |
| @@ -49,6 +51,7 @@ obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o | |||
| 49 | obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions | 51 | obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions |
| 50 | obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o | 52 | obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o |
| 51 | obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o | 53 | obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o |
| 54 | obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o | ||
| 52 | 55 | ||
| 53 | obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o | 56 | obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o |
| 54 | obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o | 57 | obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o |
| @@ -62,6 +65,7 @@ obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o | |||
| 62 | obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o | 65 | obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o |
| 63 | obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o | 66 | obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o |
| 64 | obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o | 67 | obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o |
| 68 | obj-$(CONFIG_CPU_FA526) += proc-fa526.o | ||
| 65 | obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o | 69 | obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o |
| 66 | obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o | 70 | obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o |
| 67 | obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o | 71 | obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o |
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S new file mode 100644 index 000000000000..b63a8f7b95cf --- /dev/null +++ b/arch/arm/mm/cache-fa.S | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mm/cache-fa.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Faraday Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * Based on cache-v4wb.S: | ||
| 8 | * Copyright (C) 1997-2002 Russell king | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * Processors: FA520 FA526 FA626 | ||
| 15 | */ | ||
| 16 | #include <linux/linkage.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <asm/memory.h> | ||
| 19 | #include <asm/page.h> | ||
| 20 | |||
| 21 | #include "proc-macros.S" | ||
| 22 | |||
| 23 | /* | ||
| 24 | * The size of one data cache line. | ||
| 25 | */ | ||
| 26 | #define CACHE_DLINESIZE 16 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * The total size of the data cache. | ||
| 30 | */ | ||
| 31 | #ifdef CONFIG_ARCH_GEMINI | ||
| 32 | #define CACHE_DSIZE 8192 | ||
| 33 | #else | ||
| 34 | #define CACHE_DSIZE 16384 | ||
| 35 | #endif | ||
| 36 | |||
| 37 | /* FIXME: put optimal value here. Current one is just estimation */ | ||
| 38 | #define CACHE_DLIMIT (CACHE_DSIZE * 2) | ||
| 39 | |||
| 40 | /* | ||
| 41 | * flush_user_cache_all() | ||
| 42 | * | ||
| 43 | * Clean and invalidate all cache entries in a particular address | ||
| 44 | * space. | ||
| 45 | */ | ||
| 46 | ENTRY(fa_flush_user_cache_all) | ||
| 47 | /* FALLTHROUGH */ | ||
| 48 | /* | ||
| 49 | * flush_kern_cache_all() | ||
| 50 | * | ||
| 51 | * Clean and invalidate the entire cache. | ||
| 52 | */ | ||
| 53 | ENTRY(fa_flush_kern_cache_all) | ||
| 54 | mov ip, #0 | ||
| 55 | mov r2, #VM_EXEC | ||
| 56 | __flush_whole_cache: | ||
| 57 | mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache | ||
| 58 | tst r2, #VM_EXEC | ||
| 59 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
| 60 | mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB | ||
| 61 | mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer | ||
| 62 | mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush | ||
| 63 | mov pc, lr | ||
| 64 | |||
| 65 | /* | ||
| 66 | * flush_user_cache_range(start, end, flags) | ||
| 67 | * | ||
| 68 | * Invalidate a range of cache entries in the specified | ||
| 69 | * address space. | ||
| 70 | * | ||
| 71 | * - start - start address (inclusive, page aligned) | ||
| 72 | * - end - end address (exclusive, page aligned) | ||
| 73 | * - flags - vma_area_struct flags describing address space | ||
| 74 | */ | ||
| 75 | ENTRY(fa_flush_user_cache_range) | ||
| 76 | mov ip, #0 | ||
| 77 | sub r3, r1, r0 @ calculate total size | ||
| 78 | cmp r3, #CACHE_DLIMIT @ total size >= limit? | ||
| 79 | bhs __flush_whole_cache @ flush whole D cache | ||
| 80 | |||
| 81 | 1: tst r2, #VM_EXEC | ||
| 82 | mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line | ||
| 83 | mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry | ||
| 84 | add r0, r0, #CACHE_DLINESIZE | ||
| 85 | cmp r0, r1 | ||
| 86 | blo 1b | ||
| 87 | tst r2, #VM_EXEC | ||
| 88 | mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB | ||
| 89 | mcrne p15, 0, ip, c7, c10, 4 @ data write barrier | ||
| 90 | mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush | ||
| 91 | mov pc, lr | ||
| 92 | |||
| 93 | /* | ||
| 94 | * coherent_kern_range(start, end) | ||
| 95 | * | ||
| 96 | * Ensure coherency between the Icache and the Dcache in the | ||
| 97 | * region described by start. If you have non-snooping | ||
| 98 | * Harvard caches, you need to implement this function. | ||
| 99 | * | ||
| 100 | * - start - virtual start address | ||
| 101 | * - end - virtual end address | ||
| 102 | */ | ||
| 103 | ENTRY(fa_coherent_kern_range) | ||
| 104 | /* fall through */ | ||
| 105 | |||
| 106 | /* | ||
| 107 | * coherent_user_range(start, end) | ||
| 108 | * | ||
| 109 | * Ensure coherency between the Icache and the Dcache in the | ||
| 110 | * region described by start. If you have non-snooping | ||
| 111 | * Harvard caches, you need to implement this function. | ||
| 112 | * | ||
| 113 | * - start - virtual start address | ||
| 114 | * - end - virtual end address | ||
| 115 | */ | ||
| 116 | ENTRY(fa_coherent_user_range) | ||
| 117 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
| 118 | 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry | ||
| 119 | mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry | ||
| 120 | add r0, r0, #CACHE_DLINESIZE | ||
| 121 | cmp r0, r1 | ||
| 122 | blo 1b | ||
| 123 | mov r0, #0 | ||
| 124 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB | ||
| 125 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 126 | mcr p15, 0, r0, c7, c5, 4 @ prefetch flush | ||
| 127 | mov pc, lr | ||
| 128 | |||
| 129 | /* | ||
| 130 | * flush_kern_dcache_page(kaddr) | ||
| 131 | * | ||
| 132 | * Ensure that the data held in the page kaddr is written back | ||
| 133 | * to the page in question. | ||
| 134 | * | ||
| 135 | * - kaddr - kernel address (guaranteed to be page aligned) | ||
| 136 | */ | ||
| 137 | ENTRY(fa_flush_kern_dcache_page) | ||
| 138 | add r1, r0, #PAGE_SZ | ||
| 139 | 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | ||
| 140 | add r0, r0, #CACHE_DLINESIZE | ||
| 141 | cmp r0, r1 | ||
| 142 | blo 1b | ||
| 143 | mov r0, #0 | ||
| 144 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 145 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 146 | mov pc, lr | ||
| 147 | |||
| 148 | /* | ||
| 149 | * dma_inv_range(start, end) | ||
| 150 | * | ||
| 151 | * Invalidate (discard) the specified virtual address range. | ||
| 152 | * May not write back any entries. If 'start' or 'end' | ||
| 153 | * are not cache line aligned, those lines must be written | ||
| 154 | * back. | ||
| 155 | * | ||
| 156 | * - start - virtual start address | ||
| 157 | * - end - virtual end address | ||
| 158 | */ | ||
| 159 | ENTRY(fa_dma_inv_range) | ||
| 160 | tst r0, #CACHE_DLINESIZE - 1 | ||
| 161 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
| 162 | mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry | ||
| 163 | tst r1, #CACHE_DLINESIZE - 1 | ||
| 164 | bic r1, r1, #CACHE_DLINESIZE - 1 | ||
| 165 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry | ||
| 166 | 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry | ||
| 167 | add r0, r0, #CACHE_DLINESIZE | ||
| 168 | cmp r0, r1 | ||
| 169 | blo 1b | ||
| 170 | mov r0, #0 | ||
| 171 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 172 | mov pc, lr | ||
| 173 | |||
| 174 | /* | ||
| 175 | * dma_clean_range(start, end) | ||
| 176 | * | ||
| 177 | * Clean (write back) the specified virtual address range. | ||
| 178 | * | ||
| 179 | * - start - virtual start address | ||
| 180 | * - end - virtual end address | ||
| 181 | */ | ||
| 182 | ENTRY(fa_dma_clean_range) | ||
| 183 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
| 184 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
| 185 | add r0, r0, #CACHE_DLINESIZE | ||
| 186 | cmp r0, r1 | ||
| 187 | blo 1b | ||
| 188 | mov r0, #0 | ||
| 189 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 190 | mov pc, lr | ||
| 191 | |||
| 192 | /* | ||
| 193 | * dma_flush_range(start,end) | ||
| 194 | * - start - virtual start address of region | ||
| 195 | * - end - virtual end address of region | ||
| 196 | */ | ||
| 197 | ENTRY(fa_dma_flush_range) | ||
| 198 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
| 199 | 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry | ||
| 200 | add r0, r0, #CACHE_DLINESIZE | ||
| 201 | cmp r0, r1 | ||
| 202 | blo 1b | ||
| 203 | mov r0, #0 | ||
| 204 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
| 205 | mov pc, lr | ||
| 206 | |||
| 207 | __INITDATA | ||
| 208 | |||
| 209 | .type fa_cache_fns, #object | ||
| 210 | ENTRY(fa_cache_fns) | ||
| 211 | .long fa_flush_kern_cache_all | ||
| 212 | .long fa_flush_user_cache_all | ||
| 213 | .long fa_flush_user_cache_range | ||
| 214 | .long fa_coherent_kern_range | ||
| 215 | .long fa_coherent_user_range | ||
| 216 | .long fa_flush_kern_dcache_page | ||
| 217 | .long fa_dma_inv_range | ||
| 218 | .long fa_dma_clean_range | ||
| 219 | .long fa_dma_flush_range | ||
| 220 | .size fa_cache_fns, . - fa_cache_fns | ||
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c new file mode 100644 index 000000000000..b2a6008b0111 --- /dev/null +++ b/arch/arm/mm/copypage-fa.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/copypage-fa.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Faraday Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * Based on copypage-v4wb.S: | ||
| 8 | * Copyright (C) 1995-1999 Russell King | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/highmem.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Faraday optimised copy_user_page | ||
| 19 | */ | ||
| 20 | static void __naked | ||
| 21 | fa_copy_user_page(void *kto, const void *kfrom) | ||
| 22 | { | ||
| 23 | asm("\ | ||
| 24 | stmfd sp!, {r4, lr} @ 2\n\ | ||
| 25 | mov r2, %0 @ 1\n\ | ||
| 26 | 1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\ | ||
| 27 | stmia r0, {r3, r4, ip, lr} @ 4\n\ | ||
| 28 | mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\ | ||
| 29 | add r0, r0, #16 @ 1\n\ | ||
| 30 | ldmia r1!, {r3, r4, ip, lr} @ 4\n\ | ||
| 31 | stmia r0, {r3, r4, ip, lr} @ 4\n\ | ||
| 32 | mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\ | ||
| 33 | add r0, r0, #16 @ 1\n\ | ||
| 34 | subs r2, r2, #1 @ 1\n\ | ||
| 35 | bne 1b @ 1\n\ | ||
| 36 | mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\ | ||
| 37 | ldmfd sp!, {r4, pc} @ 3" | ||
| 38 | : | ||
| 39 | : "I" (PAGE_SIZE / 32)); | ||
| 40 | } | ||
| 41 | |||
| 42 | void fa_copy_user_highpage(struct page *to, struct page *from, | ||
| 43 | unsigned long vaddr) | ||
| 44 | { | ||
| 45 | void *kto, *kfrom; | ||
| 46 | |||
| 47 | kto = kmap_atomic(to, KM_USER0); | ||
| 48 | kfrom = kmap_atomic(from, KM_USER1); | ||
| 49 | fa_copy_user_page(kto, kfrom); | ||
| 50 | kunmap_atomic(kfrom, KM_USER1); | ||
| 51 | kunmap_atomic(kto, KM_USER0); | ||
| 52 | } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Faraday optimised clear_user_page | ||
| 56 | * | ||
| 57 | * Same story as above. | ||
| 58 | */ | ||
| 59 | void fa_clear_user_highpage(struct page *page, unsigned long vaddr) | ||
| 60 | { | ||
| 61 | void *ptr, *kaddr = kmap_atomic(page, KM_USER0); | ||
| 62 | asm volatile("\ | ||
| 63 | mov r1, %2 @ 1\n\ | ||
| 64 | mov r2, #0 @ 1\n\ | ||
| 65 | mov r3, #0 @ 1\n\ | ||
| 66 | mov ip, #0 @ 1\n\ | ||
| 67 | mov lr, #0 @ 1\n\ | ||
| 68 | 1: stmia %0, {r2, r3, ip, lr} @ 4\n\ | ||
| 69 | mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\ | ||
| 70 | add %0, %0, #16 @ 1\n\ | ||
| 71 | stmia %0, {r2, r3, ip, lr} @ 4\n\ | ||
| 72 | mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\ | ||
| 73 | add %0, %0, #16 @ 1\n\ | ||
| 74 | subs r1, r1, #1 @ 1\n\ | ||
| 75 | bne 1b @ 1\n\ | ||
| 76 | mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB" | ||
| 77 | : "=r" (ptr) | ||
| 78 | : "0" (kaddr), "I" (PAGE_SIZE / 32) | ||
| 79 | : "r1", "r2", "r3", "ip", "lr"); | ||
| 80 | kunmap_atomic(kaddr, KM_USER0); | ||
| 81 | } | ||
| 82 | |||
| 83 | struct cpu_user_fns fa_user_fns __initdata = { | ||
| 84 | .cpu_clear_user_highpage = fa_clear_user_highpage, | ||
| 85 | .cpu_copy_user_highpage = fa_copy_user_highpage, | ||
| 86 | }; | ||
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S new file mode 100644 index 000000000000..08b8a955d5d7 --- /dev/null +++ b/arch/arm/mm/proc-fa526.S | |||
| @@ -0,0 +1,248 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526 | ||
| 3 | * | ||
| 4 | * Written by : Luke Lee | ||
| 5 | * Copyright (C) 2005 Faraday Corp. | ||
| 6 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * | ||
| 14 | * These are the low level assembler for performing cache and TLB | ||
| 15 | * functions on the fa526. | ||
| 16 | */ | ||
| 17 | #include <linux/linkage.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <asm/assembler.h> | ||
| 20 | #include <asm/hwcap.h> | ||
| 21 | #include <asm/pgtable-hwdef.h> | ||
| 22 | #include <asm/pgtable.h> | ||
| 23 | #include <asm/page.h> | ||
| 24 | #include <asm/ptrace.h> | ||
| 25 | #include <asm/system.h> | ||
| 26 | |||
| 27 | #include "proc-macros.S" | ||
| 28 | |||
| 29 | #define CACHE_DLINESIZE 16 | ||
| 30 | |||
| 31 | .text | ||
| 32 | /* | ||
| 33 | * cpu_fa526_proc_init() | ||
| 34 | */ | ||
| 35 | ENTRY(cpu_fa526_proc_init) | ||
| 36 | mov pc, lr | ||
| 37 | |||
| 38 | /* | ||
| 39 | * cpu_fa526_proc_fin() | ||
| 40 | */ | ||
| 41 | ENTRY(cpu_fa526_proc_fin) | ||
| 42 | stmfd sp!, {lr} | ||
| 43 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE | ||
| 44 | msr cpsr_c, ip | ||
| 45 | bl fa_flush_kern_cache_all | ||
| 46 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register | ||
| 47 | bic r0, r0, #0x1000 @ ...i............ | ||
| 48 | bic r0, r0, #0x000e @ ............wca. | ||
| 49 | mcr p15, 0, r0, c1, c0, 0 @ disable caches | ||
| 50 | nop | ||
| 51 | nop | ||
| 52 | ldmfd sp!, {pc} | ||
| 53 | |||
| 54 | /* | ||
| 55 | * cpu_fa526_reset(loc) | ||
| 56 | * | ||
| 57 | * Perform a soft reset of the system. Put the CPU into the | ||
| 58 | * same state as it would be if it had been reset, and branch | ||
| 59 | * to what would be the reset vector. | ||
| 60 | * | ||
| 61 | * loc: location to jump to for soft reset | ||
| 62 | */ | ||
| 63 | .align 4 | ||
| 64 | ENTRY(cpu_fa526_reset) | ||
| 65 | /* TODO: Use CP8 if possible... */ | ||
| 66 | mov ip, #0 | ||
| 67 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches | ||
| 68 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | ||
| 69 | #ifdef CONFIG_MMU | ||
| 70 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | ||
| 71 | #endif | ||
| 72 | mrc p15, 0, ip, c1, c0, 0 @ ctrl register | ||
| 73 | bic ip, ip, #0x000f @ ............wcam | ||
| 74 | bic ip, ip, #0x1100 @ ...i...s........ | ||
| 75 | bic ip, ip, #0x0800 @ BTB off | ||
| 76 | mcr p15, 0, ip, c1, c0, 0 @ ctrl register | ||
| 77 | nop | ||
| 78 | nop | ||
| 79 | mov pc, r0 | ||
| 80 | |||
| 81 | /* | ||
| 82 | * cpu_fa526_do_idle() | ||
| 83 | */ | ||
| 84 | .align 4 | ||
| 85 | ENTRY(cpu_fa526_do_idle) | ||
| 86 | mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt | ||
| 87 | mov pc, lr | ||
| 88 | |||
| 89 | |||
| 90 | ENTRY(cpu_fa526_dcache_clean_area) | ||
| 91 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
| 92 | add r0, r0, #CACHE_DLINESIZE | ||
| 93 | subs r1, r1, #CACHE_DLINESIZE | ||
| 94 | bhi 1b | ||
| 95 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
| 96 | mov pc, lr | ||
| 97 | |||
| 98 | /* =============================== PageTable ============================== */ | ||
| 99 | |||
| 100 | /* | ||
| 101 | * cpu_fa526_switch_mm(pgd) | ||
| 102 | * | ||
| 103 | * Set the translation base pointer to be as described by pgd. | ||
| 104 | * | ||
| 105 | * pgd: new page tables | ||
| 106 | */ | ||
| 107 | .align 4 | ||
| 108 | ENTRY(cpu_fa526_switch_mm) | ||
| 109 | #ifdef CONFIG_MMU | ||
| 110 | mov ip, #0 | ||
| 111 | #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH | ||
| 112 | mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache | ||
| 113 | #else | ||
| 114 | mcr p15, 0, ip, c7, c14, 0 @ clean and invalidate whole D cache | ||
| 115 | #endif | ||
| 116 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
| 117 | mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB since mm changed | ||
| 118 | mcr p15, 0, ip, c7, c10, 4 @ data write barrier | ||
| 119 | mcr p15, 0, ip, c7, c5, 4 @ prefetch flush | ||
| 120 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | ||
| 121 | mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB | ||
| 122 | #endif | ||
| 123 | mov pc, lr | ||
| 124 | |||
| 125 | /* | ||
| 126 | * cpu_fa526_set_pte_ext(ptep, pte, ext) | ||
| 127 | * | ||
| 128 | * Set a PTE and flush it out | ||
| 129 | */ | ||
| 130 | .align 4 | ||
| 131 | ENTRY(cpu_fa526_set_pte_ext) | ||
| 132 | #ifdef CONFIG_MMU | ||
| 133 | armv3_set_pte_ext | ||
| 134 | mov r0, r0 | ||
| 135 | mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
| 136 | mov r0, #0 | ||
| 137 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
| 138 | #endif | ||
| 139 | mov pc, lr | ||
| 140 | |||
| 141 | __INIT | ||
| 142 | |||
| 143 | .type __fa526_setup, #function | ||
| 144 | __fa526_setup: | ||
| 145 | /* On return of this routine, r0 must carry correct flags for CFG register */ | ||
| 146 | mov r0, #0 | ||
| 147 | mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 | ||
| 148 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 | ||
| 149 | #ifdef CONFIG_MMU | ||
| 150 | mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 | ||
| 151 | #endif | ||
| 152 | mcr p15, 0, r0, c7, c5, 5 @ invalidate IScratchpad RAM | ||
| 153 | |||
| 154 | mov r0, #1 | ||
| 155 | mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR | ||
| 156 | |||
| 157 | mov r0, #0 | ||
| 158 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB All | ||
| 159 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier | ||
| 160 | mcr p15, 0, r0, c7, c5, 4 @ prefetch flush | ||
| 161 | |||
| 162 | mov r0, #0x1f @ Domains 0, 1 = manager, 2 = client | ||
| 163 | mcr p15, 0, r0, c3, c0 @ load domain access register | ||
| 164 | |||
| 165 | mrc p15, 0, r0, c1, c0 @ get control register v4 | ||
| 166 | ldr r5, fa526_cr1_clear | ||
| 167 | bic r0, r0, r5 | ||
| 168 | ldr r5, fa526_cr1_set | ||
| 169 | orr r0, r0, r5 | ||
| 170 | mov pc, lr | ||
| 171 | .size __fa526_setup, . - __fa526_setup | ||
| 172 | |||
| 173 | /* | ||
| 174 | * .RVI ZFRS BLDP WCAM | ||
| 175 | * ..11 1001 .111 1101 | ||
| 176 | * | ||
| 177 | */ | ||
| 178 | .type fa526_cr1_clear, #object | ||
| 179 | .type fa526_cr1_set, #object | ||
| 180 | fa526_cr1_clear: | ||
| 181 | .word 0x3f3f | ||
| 182 | fa526_cr1_set: | ||
| 183 | .word 0x397D | ||
| 184 | |||
| 185 | __INITDATA | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Purpose : Function pointers used to access above functions - all calls | ||
| 189 | * come through these | ||
| 190 | */ | ||
| 191 | .type fa526_processor_functions, #object | ||
| 192 | fa526_processor_functions: | ||
| 193 | .word v4_early_abort | ||
| 194 | .word pabort_noifar | ||
| 195 | .word cpu_fa526_proc_init | ||
| 196 | .word cpu_fa526_proc_fin | ||
| 197 | .word cpu_fa526_reset | ||
| 198 | .word cpu_fa526_do_idle | ||
| 199 | .word cpu_fa526_dcache_clean_area | ||
| 200 | .word cpu_fa526_switch_mm | ||
| 201 | .word cpu_fa526_set_pte_ext | ||
| 202 | .size fa526_processor_functions, . - fa526_processor_functions | ||
| 203 | |||
| 204 | .section ".rodata" | ||
| 205 | |||
| 206 | .type cpu_arch_name, #object | ||
| 207 | cpu_arch_name: | ||
| 208 | .asciz "armv4" | ||
| 209 | .size cpu_arch_name, . - cpu_arch_name | ||
| 210 | |||
| 211 | .type cpu_elf_name, #object | ||
| 212 | cpu_elf_name: | ||
| 213 | .asciz "v4" | ||
| 214 | .size cpu_elf_name, . - cpu_elf_name | ||
| 215 | |||
| 216 | .type cpu_fa526_name, #object | ||
| 217 | cpu_fa526_name: | ||
| 218 | .asciz "FA526" | ||
| 219 | .size cpu_fa526_name, . - cpu_fa526_name | ||
| 220 | |||
| 221 | .align | ||
| 222 | |||
| 223 | .section ".proc.info.init", #alloc, #execinstr | ||
| 224 | |||
| 225 | .type __fa526_proc_info,#object | ||
| 226 | __fa526_proc_info: | ||
| 227 | .long 0x66015261 | ||
| 228 | .long 0xff01fff1 | ||
| 229 | .long PMD_TYPE_SECT | \ | ||
| 230 | PMD_SECT_BUFFERABLE | \ | ||
| 231 | PMD_SECT_CACHEABLE | \ | ||
| 232 | PMD_BIT4 | \ | ||
| 233 | PMD_SECT_AP_WRITE | \ | ||
| 234 | PMD_SECT_AP_READ | ||
| 235 | .long PMD_TYPE_SECT | \ | ||
| 236 | PMD_BIT4 | \ | ||
| 237 | PMD_SECT_AP_WRITE | \ | ||
| 238 | PMD_SECT_AP_READ | ||
| 239 | b __fa526_setup | ||
| 240 | .long cpu_arch_name | ||
| 241 | .long cpu_elf_name | ||
| 242 | .long HWCAP_SWP | HWCAP_HALF | ||
| 243 | .long cpu_fa526_name | ||
| 244 | .long fa526_processor_functions | ||
| 245 | .long fa_tlb_fns | ||
| 246 | .long fa_user_fns | ||
| 247 | .long fa_cache_fns | ||
| 248 | .size __fa526_proc_info, . - __fa526_proc_info | ||
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S new file mode 100644 index 000000000000..9694f1f6f485 --- /dev/null +++ b/arch/arm/mm/tlb-fa.S | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mm/tlb-fa.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Faraday Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * Based on tlb-v4wbi.S: | ||
| 8 | * Copyright (C) 1997-2002 Russell King | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * ARM architecture version 4, Faraday variation. | ||
| 15 | * This assume an unified TLBs, with a write buffer, and branch target buffer (BTB) | ||
| 16 | * | ||
| 17 | * Processors: FA520 FA526 FA626 | ||
| 18 | */ | ||
| 19 | #include <linux/linkage.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <asm/asm-offsets.h> | ||
| 22 | #include <asm/tlbflush.h> | ||
| 23 | #include "proc-macros.S" | ||
| 24 | |||
| 25 | |||
| 26 | /* | ||
| 27 | * flush_user_tlb_range(start, end, mm) | ||
| 28 | * | ||
| 29 | * Invalidate a range of TLB entries in the specified address space. | ||
| 30 | * | ||
| 31 | * - start - range start address | ||
| 32 | * - end - range end address | ||
| 33 | * - mm - mm_struct describing address space | ||
| 34 | */ | ||
| 35 | .align 4 | ||
| 36 | ENTRY(fa_flush_user_tlb_range) | ||
| 37 | vma_vm_mm ip, r2 | ||
| 38 | act_mm r3 @ get current->active_mm | ||
| 39 | eors r3, ip, r3 @ == mm ? | ||
| 40 | movne pc, lr @ no, we dont do anything | ||
| 41 | mov r3, #0 | ||
| 42 | mcr p15, 0, r3, c7, c10, 4 @ drain WB | ||
| 43 | bic r0, r0, #0x0ff | ||
| 44 | bic r0, r0, #0xf00 | ||
| 45 | 1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry | ||
| 46 | add r0, r0, #PAGE_SZ | ||
| 47 | cmp r0, r1 | ||
| 48 | blo 1b | ||
| 49 | mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB | ||
| 50 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier | ||
| 51 | mov pc, lr | ||
| 52 | |||
| 53 | |||
| 54 | ENTRY(fa_flush_kern_tlb_range) | ||
| 55 | mov r3, #0 | ||
| 56 | mcr p15, 0, r3, c7, c10, 4 @ drain WB | ||
| 57 | bic r0, r0, #0x0ff | ||
| 58 | bic r0, r0, #0xf00 | ||
| 59 | 1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry | ||
| 60 | add r0, r0, #PAGE_SZ | ||
| 61 | cmp r0, r1 | ||
| 62 | blo 1b | ||
| 63 | mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB | ||
| 64 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier | ||
| 65 | mcr p15, 0, r3, c7, c5, 4 @ prefetch flush | ||
| 66 | mov pc, lr | ||
| 67 | |||
| 68 | __INITDATA | ||
| 69 | |||
| 70 | .type fa_tlb_fns, #object | ||
| 71 | ENTRY(fa_tlb_fns) | ||
| 72 | .long fa_flush_user_tlb_range | ||
| 73 | .long fa_flush_kern_tlb_range | ||
| 74 | .long fa_tlb_flags | ||
| 75 | .size fa_tlb_fns, . - fa_tlb_fns | ||
