armv8: caches: Added routine to set non cacheable region
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Fri, 26 Jun 2015 12:35:07 +0000 (18:05 +0530)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 30 Jul 2015 23:38:12 +0000 (01:38 +0200)
Added routine mmu_set_region_dcache_behaviour() to set a
particular region as non cacheable.

Define dummy routine for mmu_set_region_dcache_behaviour()
to handle incase of dcache off.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Acked-by: Michal Simek <michal.simek@xilinx.com>
arch/arm/cpu/armv8/cache_v8.c
arch/arm/include/asm/system.h

index 254a629a3b8cae62b53c72a71336f935d4c4251e..c22f7b6a51e6c6b8209a08a8998c1e3eb314cfec 100644 (file)
@@ -139,6 +139,37 @@ int dcache_status(void)
        return (get_sctlr() & CR_C) != 0;
 }
 
+u64 *__weak arch_get_page_table(void) {
+       puts("No page table offset defined\n");
+
+       return NULL;
+}
+
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+                                    enum dcache_option option)
+{
+       u64 *page_table = arch_get_page_table();
+       u64 upto, end;
+
+       if (page_table == NULL)
+               return;
+
+       end = ALIGN(start + size, (1 << MMU_SECTION_SHIFT)) >>
+             MMU_SECTION_SHIFT;
+       start = start >> MMU_SECTION_SHIFT;
+       for (upto = start; upto < end; upto++) {
+               page_table[upto] &= ~PMD_ATTRINDX_MASK;
+               page_table[upto] |= PMD_ATTRINDX(option);
+       }
+       asm volatile("dsb sy");
+       __asm_invalidate_tlb_all();
+       asm volatile("dsb sy");
+       asm volatile("isb");
+       start = start << MMU_SECTION_SHIFT;
+       end = end << MMU_SECTION_SHIFT;
+       flush_dcache_range(start, end);
+       asm volatile("dsb sy");
+}
 #else  /* CONFIG_SYS_DCACHE_OFF */
 
 void invalidate_dcache_all(void)
@@ -170,6 +201,11 @@ int dcache_status(void)
        return 0;
 }
 
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+                                    enum dcache_option option)
+{
+}
+
 #endif /* CONFIG_SYS_DCACHE_OFF */
 
 #ifndef CONFIG_SYS_ICACHE_OFF
index 760e8ab1c8c19a7acb1a2336037e009937b8733a..868ea54b4fef2c2d9d9819a986ca58f5e9c7800b 100644 (file)
 #define CR_EE          (1 << 25)       /* Exception (Big) Endian       */
 
 #define PGTABLE_SIZE   (0x10000)
+/* 2MB granularity */
+#define MMU_SECTION_SHIFT      21
 
 #ifndef __ASSEMBLY__
 
+enum dcache_option {
+       DCACHE_OFF = 0x3,
+};
+
 #define isb()                          \
        ({asm volatile(                 \
        "isb" : : : "memory");          \
@@ -264,16 +270,6 @@ enum {
 #define TTBR0_IRGN_WB                  (1 << 0 | 1 << 6)
 #endif
 
-/**
- * Change the cache settings for a region.
- *
- * \param start                start address of memory region to change
- * \param size         size of memory region to change
- * \param option       dcache option to select
- */
-void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
-                                    enum dcache_option option);
-
 /**
  * Register an update to the page tables, and flush the TLB
  *
@@ -295,4 +291,17 @@ phys_addr_t noncached_alloc(size_t size, size_t align);
 
 #endif /* CONFIG_ARM64 */
 
+#ifndef __ASSEMBLY__
+/**
+ * Change the cache settings for a region.
+ *
+ * \param start                start address of memory region to change
+ * \param size         size of memory region to change
+ * \param option       dcache option to select
+ */
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+                                    enum dcache_option option);
+
+#endif /* __ASSEMBLY__ */
+
 #endif