فهرست منبع

Merge pull request #2523 from qz721/libcpu_cortex_a

Add standard rt-thread cache interfaces for arm/cortex-a.
Bernard Xiong 6 سال پیش
والد
کامیت
459ddc3b06
2فایلهای تغییر یافته به همراه96 افزوده شده و 1 حذف شده
  1. 94 0
      libcpu/arm/cortex-a/cache.c
  2. 2 1
      libcpu/arm/cortex-a/mmu.h

+ 94 - 0
libcpu/arm/cortex-a/cache.c

@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-03-29 	  quanzhao 	   the first version
+ */
+#include <rthw.h>
+#include <rtdef.h>
+
+rt_inline rt_uint32_t rt_cpu_icache_line_size(void)
+{
+    rt_uint32_t ctr;
+    asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
+    return 4 << (ctr & 0xF);
+}
+
+rt_inline rt_uint32_t rt_cpu_dcache_line_size(void)
+{
+    rt_uint32_t ctr;
+    asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
+    return 4 << ((ctr >> 16) & 0xF);
+}
+
+void rt_hw_cpu_icache_invalidate(void *addr, int size)
+{
+    rt_uint32_t line_size = rt_cpu_icache_line_size();
+    rt_uint32_t start_addr = (rt_uint32_t)addr;
+    rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+    start_addr &= ~(line_size-1);
+    end_addr &= ~(line_size-1);
+    while (start_addr < end_addr)
+    {
+        asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r"(start_addr));  /* icimvau */
+        start_addr += line_size;
+    }
+}
+
+void rt_hw_cpu_dcache_invalidate(void *addr, int size)
+{
+    rt_uint32_t line_size = rt_cpu_dcache_line_size();
+    rt_uint32_t start_addr = (rt_uint32_t)addr;
+    rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+    start_addr &= ~(line_size-1);
+    end_addr &= ~(line_size-1);
+    while (start_addr < end_addr)
+    {
+        asm volatile ("mcr p15, 0, %0, c7, c6, 1" :: "r"(start_addr));  /* dcimvac */
+        start_addr += line_size;
+    }
+}
+
+void rt_hw_cpu_dcache_clean(void *addr, int size)
+{
+    rt_uint32_t line_size = rt_cpu_dcache_line_size();
+    rt_uint32_t start_addr = (rt_uint32_t)addr;
+    rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+    start_addr &= ~(line_size-1);
+    end_addr &= ~(line_size-1);
+    while (start_addr < end_addr)
+    {
+        asm volatile ("mcr p15, 0, %0, c7, c10, 1" :: "r"(start_addr)); /* dccmvac */
+        start_addr += line_size;
+    }
+}
+
+void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_INVALIDATE)
+        rt_hw_cpu_icache_invalidate(addr, size);
+}
+
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH)
+        rt_hw_cpu_dcache_clean(addr, size);
+    else if (ops == RT_HW_CACHE_INVALIDATE)
+        rt_hw_cpu_dcache_invalidate(addr, size);
+}
+
+rt_base_t rt_hw_cpu_icache_status(void)
+{
+    return 0;
+}
+
+rt_base_t rt_hw_cpu_dcache_status(void)
+{
+    return 0;
+}

+ 2 - 1
libcpu/arm/cortex-a/mmu.h

@@ -13,6 +13,7 @@
 #include <rtthread.h>
 
 #define DESC_SEC       (0x2)
+#define MEMWBWA        ((1<<12)|(3<<2))     /* write back, write allocate */
 #define MEMWB          (3<<2)  /* write back, no write allocate */
 #define MEMWT          (2<<2)  /* write through, no write allocate */
 #define SHAREDEVICE    (1<<2)  /* shared device */
@@ -34,7 +35,7 @@
 /* device mapping type */
 #define DEVICE_MEM     (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
 /* normal memory mapping type */
-#define NORMAL_MEM     (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC)
+#define NORMAL_MEM     (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC)
 
 struct mem_desc
 {