This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 784035a3e9c arch/mips/jz4780: Add support for L2 cache operations
784035a3e9c is described below

commit 784035a3e9cb8c0c38d73e4bd38d7fbbe29aaa64
Author: Lwazi Dube <[email protected]>
AuthorDate: Mon Jul 20 19:00:19 2026 -0400

    arch/mips/jz4780: Add support for L2 cache operations
    
    The common mips_cache.S only handles generic L1 cache operations and
    does not support L2 (secondary) cache operations required for the
    JZ4780 target.
    
    This commit introduces mti_cache.S to support both L1 and L2 cache
    operations.
    
    The mti_cache.S implementation is BSD licensed from Imagination
    Technologies.
    
    Signed-off-by: Lwazi Dube <[email protected]>
---
 arch/mips/Kconfig                               |   4 +-
 arch/mips/src/jz4780/Make.defs                  |   8 +-
 arch/mips/src/jz4780/chip.h                     |   2 +
 arch/mips/src/jz4780/jz4780_cache.c             | 442 ++++++++++++++++
 arch/mips/src/jz4780/{chip.h => jz4780_cache.h} |  46 +-
 arch/mips/src/jz4780/jz4780_lowinit.c           |   3 +
 arch/mips/src/jz4780/jz4780_timerisr.c          |   2 +-
 arch/mips/src/jz4780/mti_cache.S                | 664 ++++++++++++++++++++++++
 boards/mips/jz4780/ci20/configs/net/defconfig   |   8 +-
 boards/mips/jz4780/ci20/configs/nsh/defconfig   |   8 +-
 10 files changed, 1158 insertions(+), 29 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0580fb2dfe8..1d1f2a2965d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -34,12 +34,12 @@ config ARCH_CHIP_JZ4780
        bool "JZ4780"
        select ARCH_MIPS32
        select ARCH_MIPS_XBURST1
+       select ARCH_DCACHE
+       select ARCH_ICACHE
        select ARCH_HAVE_IRQPRIO
        select ARCH_VECNOTIRQ
        select ARCH_HAVE_RESET
        select ARCH_HAVE_SERIAL_TERMIOS
-       select MIPS32_HAVE_DCACHE
-       select MIPS32_HAVE_ICACHE
        select MIPS32_USE_WAIT_INSTRUCTION
        select MIPS32_USE_SYSCALL_INSTRUCTION
        ---help---
diff --git a/arch/mips/src/jz4780/Make.defs b/arch/mips/src/jz4780/Make.defs
index 8684ef2b249..a13a6faaa4b 100644
--- a/arch/mips/src/jz4780/Make.defs
+++ b/arch/mips/src/jz4780/Make.defs
@@ -26,7 +26,7 @@ HEAD_ASRC = jz4780_head.S
 
 # Common MIPS files
 
-CMN_ASRCS  = mips_syscall0.S fork.S mips_cache.S
+CMN_ASRCS  = mips_syscall0.S fork.S
 CMN_CSRCS += mips_allocateheap.c mips_copystate.c mips_createstack.c
 CMN_CSRCS += mips_doirq.c mips_exit.c mips_getintstack.c mips_initialize.c
 CMN_CSRCS += mips_initialstate.c mips_irq.c mips_lowputs.c
@@ -44,6 +44,10 @@ endif
 
 # Required JZ4780 files
 
-CHIP_ASRCS  =
+ifeq ($(CONFIG_ALLOW_BSD_COMPONENTS),y)
+CHIP_ASRCS  = mti_cache.S
+endif
+
 CHIP_CSRCS  = jz4780_lowinit.c jz4780_exception.c jz4780_decodeirq.c
 CHIP_CSRCS += jz4780_irq.c jz4780_timerisr.c jz4780_gpio.c
+CHIP_CSRCS += jz4780_cache.c
diff --git a/arch/mips/src/jz4780/chip.h b/arch/mips/src/jz4780/chip.h
index 58884353e1b..63b0c4710c5 100644
--- a/arch/mips/src/jz4780/chip.h
+++ b/arch/mips/src/jz4780/chip.h
@@ -34,6 +34,8 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+#define JZ4780_DCACHE_LINESIZE 32
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
diff --git a/arch/mips/src/jz4780/jz4780_cache.c 
b/arch/mips/src/jz4780/jz4780_cache.c
new file mode 100644
index 00000000000..3777118e933
--- /dev/null
+++ b/arch/mips/src/jz4780/jz4780_cache.c
@@ -0,0 +1,442 @@
+/****************************************************************************
+ * arch/mips/src/jz4780/jz4780_cache.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include <nuttx/cache.h>
+#include <nuttx/debug.h>
+#include <nuttx/spinlock.h>
+
+#include <arch/board/board.h>
+
+#include "jz4780_cache.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static spinlock_t g_cache_lock = SP_UNLOCKED;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_ICACHE
+
+/****************************************************************************
+ * Name: up_get_icache_linesize
+ *
+ * Description:
+ *   Get icache linesize
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Cache line size
+ *
+ ****************************************************************************/
+
+size_t up_get_icache_linesize(void)
+{
+  return mips_icache_linesize;
+}
+
+/****************************************************************************
+ * Name: up_get_icache_size
+ *
+ * Description:
+ *   Get icache size
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Cache size
+ *
+ ****************************************************************************/
+
+size_t up_get_icache_size(void)
+{
+  return mips_icache_size;
+}
+
+/****************************************************************************
+ * Name: up_invalidate_icache_all
+ *
+ * Description:
+ *   Invalidate all instruction caches to PoU, also flushes branch target
+ *   cache
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_invalidate_icache_all(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_invalidate_icache
+ *
+ * Description:
+ *   Validate the specified range instruction cache as PoU,
+ *   and flush the branch target cache
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_invalidate_icache(uintptr_t start, uintptr_t end)
+{
+}
+
+/****************************************************************************
+ * Name: up_enable_icache
+ *
+ * Description:
+ *   Enable the I-Cache
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_enable_icache(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_disable_icache
+ *
+ * Description:
+ *   Disable the I-Cache
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_disable_icache(void)
+{
+}
+
+#endif /* CONFIG_ARCH_ICACHE */
+
+#ifdef CONFIG_ARCH_DCACHE
+
+/****************************************************************************
+ * Name: up_get_dcache_linesize
+ *
+ * Description:
+ *   Get dcache linesize
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Cache line size
+ *
+ ****************************************************************************/
+
+size_t up_get_dcache_linesize(void)
+{
+  return mips_dcache_linesize;
+}
+
+/****************************************************************************
+ * Name: up_get_dcache_size
+ *
+ * Description:
+ *   Get dcache size
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Cache size
+ *
+ ****************************************************************************/
+
+size_t up_get_dcache_size(void)
+{
+  return mips_dcache_size;
+}
+
+/****************************************************************************
+ * Name: up_invalidate_dcache
+ *
+ * Description:
+ *   Invalidate the data cache within the specified region; we will be
+ *   performing a DMA operation in this region and we want to purge old data
+ *   in the cache.
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This operation is not atomic.  This function assumes that the caller
+ *   has exclusive access to the address range so that no harm is done if
+ *   the operation is preempted.
+ *
+ ****************************************************************************/
+
+void up_invalidate_dcache(uintptr_t start, uintptr_t end)
+{
+  if (end > start)
+    {
+      if ((end - start) % mips_dcache_linesize == 0)
+        {
+          m32_dcache_invalidate(start, end - start);
+        }
+      else
+        {
+          m32_dcache_clean_invalidate(start, end - start);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: up_invalidate_dcache_all
+ *
+ * Description:
+ *   Invalidate the entire contents of D cache.
+ *
+ *   NOTE: This function forces L1 and L2 cache operations to be atomic
+ *   by disabling interrupts.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_invalidate_dcache_all(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_clean_dcache
+ *
+ * Description:
+ *   Clean the data cache within the specified region by flushing the
+ *   contents of the data cache to memory.
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This operation is not atomic.  This function assumes that the caller
+ *   has exclusive access to the address range so that no harm is done if
+ *   the operation is preempted.
+ *
+ ****************************************************************************/
+
+void up_clean_dcache(uintptr_t start, uintptr_t end)
+{
+  if (end > start)
+    {
+      m32_dcache_clean(start, end - start);
+    }
+}
+
+/****************************************************************************
+ * Name: up_clean_dcache_all
+ *
+ * Description:
+ *   Clean the entire data cache within the specified region by flushing the
+ *   contents of the data cache to memory.
+ *
+ *   NOTE: This operation is un-necessary if the DCACHE is configured in
+ *   write-through mode.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This operation is not atomic.  This function assumes that the caller
+ *   has exclusive access to the address range so that no harm is done if
+ *   the operation is preempted.
+ *
+ ****************************************************************************/
+
+void up_clean_dcache_all(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_flush_dcache
+ *
+ * Description:
+ *   Flush the data cache within the specified region by cleaning and
+ *   invalidating the D cache.
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This operation is not atomic.  This function assumes that the caller
+ *   has exclusive access to the address range so that no harm is done if
+ *   the operation is preempted.
+ *
+ ****************************************************************************/
+
+void up_flush_dcache(uintptr_t start, uintptr_t end)
+{
+  if (start % mips_dcache_linesize != 0)
+    {
+      start = start - start % mips_dcache_linesize;
+    }
+
+  if (end > start)
+    {
+      m32_dcache_clean_invalidate(start, end - start);
+    }
+}
+
+/****************************************************************************
+ * Name: up_flush_dcache_all
+ *
+ * Description:
+ *   Flush the entire data cache by cleaning and invalidating the D cache.
+ *
+ *   NOTE: If DCACHE write-through is configured, then this operation is the
+ *   same as up_invalidate_cache_all().
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This operation is not atomic.  This function assumes that the caller
+ *   has exclusive access to the address range so that no harm is done if
+ *   the operation is preempted.
+ *
+ ****************************************************************************/
+
+void up_flush_dcache_all(void)
+{
+  irqstate_t flags;
+  flags = spin_lock_irqsave(&g_cache_lock);
+  m32_flush_dcache();
+  spin_unlock_irqrestore(&g_cache_lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_enable_dcache
+ *
+ * Description:
+ *   Enable the D-Cache
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_enable_dcache(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_disable_dcache
+ *
+ * Description:
+ *   Disable the D-Cache
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_disable_dcache(void)
+{
+}
+
+/****************************************************************************
+ * Name: up_coherent_dcache
+ *
+ * Description:
+ *   Ensure that the I and D caches are coherent within specified region
+ *   by cleaning the D cache (i.e., flushing the D cache contents to memory
+ *   and invalidating the I cache. This is typically used when code has been
+ *   written to a memory region, and will be executed.
+ *
+ * Input Parameters:
+ *   addr - virtual start address of region
+ *   len  - Size of the address region in bytes
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_coherent_dcache(uintptr_t addr, size_t len)
+{
+}
+
+#endif /* CONFIG_ARCH_DCACHE */
diff --git a/arch/mips/src/jz4780/chip.h b/arch/mips/src/jz4780/jz4780_cache.h
similarity index 69%
copy from arch/mips/src/jz4780/chip.h
copy to arch/mips/src/jz4780/jz4780_cache.h
index 58884353e1b..21c8b234ea8 100644
--- a/arch/mips/src/jz4780/chip.h
+++ b/arch/mips/src/jz4780/jz4780_cache.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/mips/src/jz4780/chip.h
+ * arch/mips/src/jz4780/jz4780_cache.h
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -20,15 +20,21 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_MIPS_SRC_JZ4780_CHIP_H
-#define __ARCH_MIPS_SRC_JZ4780_CHIP_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#include <arch/jz4780/chip.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include <nuttx/cache.h>
+#include <nuttx/debug.h>
+
+#include <arch/board/board.h>
+
+#ifndef __ARCH_MIPS_SRC_JZ4780_JZ4780_CACHE_H
+#define __ARCH_MIPS_SRC_JZ4780_JZ4780_CACHE_H
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -44,10 +50,6 @@
  * Inline Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
 #ifdef __cplusplus
 #define EXTERN extern "C"
 extern "C"
@@ -56,10 +58,34 @@ extern "C"
 #define EXTERN extern
 #endif
 
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+void m32_size_cache(void);
+void m32_flush_dcache(void);
+void m32_flush_icache(void);
+void m32_clean_cache(uint32_t kva, size_t n);
+void m32_sync_icache(uint32_t kva, size_t n);
+void m32_dcache_clean_invalidate(uint32_t kva, size_t n);
+void m32_dcache_invalidate(uint32_t kva, size_t n);
+void m32_dcache_clean(unsigned kva, size_t n);
+
+extern int mips_icache_size;
+extern int mips_icache_linesize;
+extern int mips_icache_ways;
+extern int mips_dcache_size;
+extern int mips_dcache_linesize;
+extern int mips_dcache_ways;
+extern int mips_scache_size;
+extern int mips_scache_linesize;
+extern int mips_scache_ways;
+
 #undef EXTERN
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __ASSEMBLY__ */
-#endif /* __ARCH_MIPS_SRC_JZ4780_CHIP_H */
+#endif /* __ARCH_MIPS_SRC_JZ4780_JZ4780_CACHE_H */
+
diff --git a/arch/mips/src/jz4780/jz4780_lowinit.c 
b/arch/mips/src/jz4780/jz4780_lowinit.c
index 46b56509172..0e066e05f7b 100644
--- a/arch/mips/src/jz4780/jz4780_lowinit.c
+++ b/arch/mips/src/jz4780/jz4780_lowinit.c
@@ -37,6 +37,7 @@
 #include "mips_internal.h"
 
 #include "jz4780_lowinit.h"
+#include "jz4780_cache.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -95,6 +96,8 @@ static inline void jz4780_pbclk(void)
 
 void jz4780_lowinit(void)
 {
+  m32_size_cache();
+
   /* Configure peripheral clocking */
 
   jz4780_pbclk();
diff --git a/arch/mips/src/jz4780/jz4780_timerisr.c 
b/arch/mips/src/jz4780/jz4780_timerisr.c
index ceb633edb43..9e1ee6bfeda 100644
--- a/arch/mips/src/jz4780/jz4780_timerisr.c
+++ b/arch/mips/src/jz4780/jz4780_timerisr.c
@@ -61,7 +61,7 @@ static void reboot_s(int sec)
 }
 
 /****************************************************************************
- * Function:  jzjz_timerisr
+ * Function:  jz_timerisr
  *
  * Description:
  *   The timer ISR will perform a variety of services for various portions
diff --git a/arch/mips/src/jz4780/mti_cache.S b/arch/mips/src/jz4780/mti_cache.S
new file mode 100644
index 00000000000..8098bd3a992
--- /dev/null
+++ b/arch/mips/src/jz4780/mti_cache.S
@@ -0,0 +1,664 @@
+/****************************************************************************
+ * arch/mips/src/jz4780/mti_cache.S
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright 2014-2015, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "mips32-memorymap.h"
+
+#ifdef CONFIG_ALLOW_BSD_COMPONENTS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define FUNCTION(x) .global x; .type x, STT_FUNC; x:
+#define DATA(x) .global x; .type x, STT_OBJECT; x:
+
+/* Cache operations */
+
+#define Index_Invalidate_I               0x00        /* 0       0 */
+#define Index_Writeback_Inv_D            0x01        /* 0       1 */
+#define Index_Writeback_Inv_T            0x02        /* 0       2 */
+#define Index_Writeback_Inv_S            0x03        /* 0       3 */
+#define Index_Load_Tag_I                 0x04        /* 1       0 */
+#define Index_Load_Tag_D                 0x05        /* 1       1 */
+#define Index_Load_Tag_T                 0x06        /* 1       2 */
+#define Index_Load_Tag_S                 0x07        /* 1       3 */
+#define Index_Store_Tag_I                0x08        /* 2       0 */
+#define Index_Store_Tag_D                0x09        /* 2       1 */
+#define Index_Store_Tag_T                0x0A        /* 2       2 */
+#define Index_Store_Tag_S                0x0B        /* 2       3 */
+#define Hit_Invalidate_I                 0x10        /* 4       0 */
+#define Hit_Invalidate_D                 0x11        /* 4       1 */
+#define Hit_Invalidate_T                 0x12        /* 4       2 */
+#define Hit_Invalidate_S                 0x13        /* 4       3 */
+#define Fill_I                           0x14        /* 5       0 */
+#define Hit_Writeback_Inv_D              0x15        /* 5       1 */
+#define Hit_Writeback_Inv_T              0x16        /* 5       2 */
+#define Hit_Writeback_Inv_S              0x17        /* 5       3 */
+#define Hit_Writeback_D                  0x19        /* 6       1 */
+#define Hit_Writeback_T                  0x1A        /* 6       2 */
+#define Hit_Writeback_S                  0x1B        /* 6       3 */
+#define Fetch_Lock_I                     0x1C        /* 7       0 */
+#define Fetch_Lock_D                     0x1D        /* 7       1 */
+#define Fetch_Lock_S                     0x1F        /* 7       3 */
+
+#define C0_CONFIG                        $16
+#define C0_CONFIG0                       $16, 0
+#define C0_CONFIG1                       $16, 1
+#define C0_CONFIG2                       $16, 2
+#define C0_CONFIG3                       $16, 3
+#define C0_CONFIG4                       $16, 4
+#define C0_CONFIG5                       $16, 5
+
+#define  CFG1_IL_SHIFT                   19
+#define  CFG1_IL_BITS                    3
+#define  CFG1_IS_SHIFT                   22  /* Unless n==7, then 32 */
+#define  CFG1_IS_BITS                    3
+#define  CFG1_IA_SHIFT                   16
+#define  CFG1_IA_BITS                    3
+#define  CFG1_DS_SHIFT                   13
+#define  CFG1_DS_BITS                    3
+#define  CFG1_DL_SHIFT                   10
+#define  CFG1_DL_BITS                    3
+#define  CFG1_DA_SHIFT                   7
+#define  CFG1_DA_BITS                    3
+
+#define  CFG2_SS_SHIFT                   8
+#define  CFG2_SS_BITS                    4
+#define  CFG2_SL_SHIFT                   4
+#define  CFG2_SL_BITS                    4
+#define  CFG2_SA_SHIFT                   0
+#define  CFG2_SA_BITS                    4
+
+#define  CFG3_M_SHIFT                    31
+#define  CFG4_M_SHIFT                    31
+#define  CFG5_L2C_SHIFT                  10
+
+/* Global data declaration with size. */
+
+#define EXPORTS(name, sz)     \
+  .globl name;                \
+  .type name, @object;        \
+  .size name, sz;             \
+name:
+
+#define DECL(x, val)          \
+  EXPORTS(x, 4);              \
+  .word  val
+
+#define PTR_SUBU  subu  /* decrement pointer (SGI uses sub) */
+#define PTR_ADDU  addu  /* increment pointer (SGI uses add) */
+#define PTR_MFC0  mfc0  /* access CP0 pointer width register */
+#define PTR_MTC0  mtc0  /* access CP0 pointer width register */
+
+/* Macros to automate cache operations */
+
+#define addr     $t0
+#define maxaddr  $t1
+#define mask     $t2
+
+#define cacheop(kva, n, linesize, op)          \
+  /* check for bad size */                     \
+  blez  n, 11f ;                               \
+  PTR_ADDU maxaddr, kva, n ;                   \
+  /* align to line boundaries */               \
+  PTR_SUBU mask, linesize, 1 ;                 \
+  not  mask ;                                  \
+  and  addr, kva, mask ;                       \
+  PTR_SUBU addr, linesize ;                    \
+  PTR_ADDU maxaddr, -1 ;                       \
+  and  maxaddr, mask ;                         \
+  /* the cacheop loop */                       \
+10:  PTR_ADDU addr, linesize ;                 \
+  cache  op, 0(addr) ;                         \
+  bne  addr, maxaddr, 10b ;                    \
+11:
+
+/* virtual cache op: no limit on size of region */
+
+#define vcacheop(kva, n, linesize, op)         \
+  cacheop(kva, n, linesize, op)
+
+/* indexed cache op: region limited to cache size */
+
+#define icacheop(kva, n, linesize, size, op)   \
+    move     $t3, n;                           \
+    bltu     n, size, 12f;                     \
+    move     $t3, size;                        \
+12:  cacheop(kva, $t3, linesize, op)
+
+
+/* caches may not have been sized yet */
+
+#define SIZE_CACHE(reg, which)                 \
+    lw       reg, which;                       \
+9:  blez     reg, 9f;                          \
+    sync
+
+#define tmp         $t0
+#define cfg         $t1
+#define icachesize  $t2
+#define ilinesize   $t3
+#define iways       $ta0
+#define dcachesize  $ta1
+#define dlinesize   $ta2
+#define dways       $ta3
+#define scachesize  $t8
+#define slinesize   $t9
+#define sways       $v0
+#define tmp1        $v1
+#define tmp2        $a0
+#define tmp3        $a1
+#define tmp4        $a2
+#define tmp5        $a3
+
+.set nomips16
+
+DECL(mips_icache_size, -1)
+DECL(mips_icache_linesize, -1)
+DECL(mips_icache_ways, 1)
+
+DECL(mips_dcache_size, -1)
+DECL(mips_dcache_linesize, -1)
+DECL(mips_dcache_ways, 1)
+
+DECL(mips_scache_size, -1)
+DECL(mips_scache_linesize, -1)
+DECL(mips_scache_ways, 1)
+
+/****************************************************************************
+ *
+ * void m32_size_cache()
+ *
+ * Work out size of I, D & S caches (assume already initialised)
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_size_cache)
+    lw       $t0, mips_icache_size
+    move     tmp3, $ra
+    bgtz     $t0, 8f        # already known?
+
+    bal      _size_cache
+    move     $ra, tmp3
+
+8:  # Return
+    jr       $ra
+
+
+/****************************************************************************
+ *
+ * void m32_clean_icache (unsigned kva, size_t n)
+ *
+ * Writeback and invalidate address range in instruction caches
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_clean_icache)
+    SIZE_CACHE($a2, mips_icache_linesize)
+    vcacheop($a0, $a1, $a2, Hit_Invalidate_I)
+
+    lw       $a2, mips_scache_linesize
+    blez     $a2, 9f
+    vcacheop($a0, $a1, $a2, Hit_Writeback_Inv_S)
+    sync
+
+9:  jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * static void _size_cache()
+ *
+ * Internal routine to determine cache sizes by looking at config
+ * registers.  Sizes are returned in registers, as follows:
+ *
+ * Do not use tmp3 (reg a1) and tmp1 (reg v1) in this function.
+ *
+ ****************************************************************************/
+
+FUNCTION(_size_cache)
+    # Read $config, 0 to check presence of $config, 1
+    mfc0     cfg, C0_CONFIG
+
+    # Read Configuration register, select 1
+    mfc0     cfg, C0_CONFIG1
+
+    # Get I-cache line size
+    ext      tmp, cfg, CFG1_IL_SHIFT, CFG1_IL_BITS
+    beqz     tmp, 8f    # No I-cache
+
+    # Get number of I-cache ways
+    ext      iways, cfg, CFG1_IA_SHIFT, CFG1_IA_BITS
+    addiu    iways, iways, 1
+    move     icachesize, iways
+
+    # Total icache size = lines/way * linesize * ways
+    li       ilinesize, 1
+    addiu    tmp, tmp, 1
+    sllv     ilinesize, ilinesize, tmp
+    sllv     icachesize, icachesize, tmp
+
+    # Get I-cache lines per way
+    ext      tmp, cfg, CFG1_IS_SHIFT, CFG1_IS_BITS
+    addiu    tmp, tmp, 1
+    andi     tmp, tmp, 7
+    addiu    tmp, tmp, 5
+    sllv     icachesize, icachesize, tmp
+
+    # Store icache config
+    sw       icachesize, mips_icache_size
+    sw       ilinesize, mips_icache_linesize
+    sw       iways, mips_icache_ways
+
+8:  # No I-cache, check for D-cache
+    ext      tmp, cfg, CFG1_DL_SHIFT, CFG1_DL_BITS
+    beqz     tmp, 9f          # No D-cache
+
+    # Get number of dcache ways
+    ext      dways, cfg, CFG1_DA_SHIFT, CFG1_DA_BITS
+    addiu    dways, dways, 1
+    move     dcachesize, dways
+
+    # Total dcache size = lines/way * linesize * ways
+    li       dlinesize, 1
+    addiu    tmp, tmp, 1
+    sllv     dlinesize, dlinesize, tmp
+    sllv     dcachesize, dcachesize, tmp
+
+    # Get dcache lines per way
+    ext      tmp, cfg, CFG1_DS_SHIFT, CFG1_DS_BITS
+    addiu    tmp, tmp, 1
+    andi     tmp, tmp, 7
+    addiu    tmp, tmp, 5
+    sllv     dcachesize, dcachesize, tmp
+
+    # Store dcache config
+    sw       dcachesize, mips_dcache_size
+    sw       dlinesize, mips_dcache_linesize
+    sw       dways, mips_dcache_ways
+9:
+    LA       tmp, __cache_size_hook
+    move     tmp4, $ra
+    jal      tmp
+    move     $ra, tmp4
+
+    # Return
+    jr       $ra
+
+/****************************************************************************
+ *
+ * static void __cache_size_hook()
+ *
+ * Internal routine to determine cache sizes by looking at config
+ * registers.  Sizing information is stored directly to memory.
+ *
+ * Do not use tmp3 (reg a1), tmp1 (reg v1) or tmp4 (a2) in this function.
+ *
+ ****************************************************************************/
+
+FUNCTION(__cache_size_hook)
+
+    # If we are operating with a coherency manager, abort.
+    # Check if we have config 5 register present
+    mfc0     tmp, C0_CONFIG3
+    ext      tmp, tmp, CFG3_M_SHIFT, 1
+    beqz     tmp, 2f
+
+    mfc0     tmp, C0_CONFIG4
+    ext      tmp, tmp, CFG4_M_SHIFT, 1
+    beqz     tmp, 2f
+
+    # Do we have a memory mapped L2 cache config?
+    mfc0     tmp, C0_CONFIG5
+    ext      tmp, tmp, CFG5_L2C_SHIFT, 1
+    beqz     tmp, 2f
+
+    # No CM3 code supplied but we have a memory mapped L2 config
+    # Report a Boot failure through UHI
+    li       $t9, 23
+    # Reason - L2 cache config
+    li       $a0, 1
+    # Syscall number
+    li       $v0, 1
+    # Trigger the UHI operation
+    syscall  1
+    # Should never return
+1:
+    b        1b
+
+2:  mfc0     cfg, C0_CONFIG2
+
+    # Get scache line size (log2)
+    ext      tmp, cfg, CFG2_SL_SHIFT, CFG2_SL_BITS
+    beqz     tmp, 3f    # no s-cache
+    addiu    tmp, tmp, 1
+
+    # Get number of scache ways
+    ext      sways, cfg, CFG2_SA_SHIFT, CFG2_SA_BITS
+    addiu    sways, sways, 1
+    move     scachesize, sways
+
+    # Total scache size = lines/way * linesize * ways
+    li       slinesize, 1
+    sllv     slinesize, slinesize, tmp
+    sllv     scachesize, scachesize, tmp
+
+    # Get scache lines per way
+    ext      tmp, cfg, CFG2_SS_SHIFT, CFG2_SS_BITS
+    addiu    tmp, tmp, 6
+    sllv     scachesize, scachesize, tmp
+
+    sw       scachesize, mips_scache_size
+    sw       slinesize, mips_scache_linesize
+    sw       sways, mips_scache_ways
+3:
+    # Return
+    jr       $ra
+
+
+/****************************************************************************
+ *
+ * void m32_flush_cache (void)
+ *
+ * Writeback and invalidate all caches
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_flush_cache)
+    SIZE_CACHE($a1, mips_dcache_size)
+
+    /* writeback and invalidate primary caches individually */
+    lw       $a2, mips_dcache_linesize
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Writeback_Inv_D)
+
+9:  lw       $a1, mips_icache_size
+    lw       $a2, mips_icache_linesize
+    blez     $a1, 9f
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Invalidate_I)
+
+9:  lw       $a1, mips_scache_size
+    lw       $a2, mips_scache_linesize
+    blez     $a1, 9f
+    sync
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Writeback_Inv_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_flush_dcache (void)
+ *
+ * Writeback and invalidate data caches only
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_flush_dcache)
+    SIZE_CACHE($a1, mips_dcache_size)
+
+    /* writeback and invalidate primary data cache */
+    lw       $a2, mips_dcache_linesize
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Writeback_Inv_D)
+
+9:  lw       $a1, mips_scache_size
+    lw       $a2, mips_scache_linesize
+    blez     $a1, 9f
+    sync
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Writeback_Inv_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_flush_icache (void)
+ *
+ * Writeback and invalidate instruction cache only
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_flush_icache)
+  SIZE_CACHE($a1, mips_icache_size)
+
+    /* writeback and invalidate primary instruction cache */
+    lw       $a2, mips_icache_linesize
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Invalidate_I)
+
+9:  lw       $a1, mips_scache_size
+    blez     $a1, 9f
+    lw       $a2, mips_scache_linesize
+    li       $a0, KSEG0_BASE
+    cacheop($a0, $a1, $a2, Index_Writeback_Inv_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_clean_cache (unsigned kva, size_t n)
+ *
+ * Writeback and invalidate address range in all caches
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_clean_cache)
+    SIZE_CACHE($a2, mips_dcache_linesize)
+    vcacheop($a0, $a1, $a2, Hit_Writeback_Inv_D)
+
+9:  lw       $a2, mips_icache_linesize
+    blez     $a2, 9f
+    vcacheop($a0, $a1, $a2, Hit_Invalidate_I)
+
+9:  lw       $a2, mips_scache_linesize
+    blez     $a2, 9f
+
+    sync
+    vcacheop($a0, $a1, $a2, Hit_Writeback_Inv_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_sync_icache (unsigned kva, size_t n)
+ *
+ * Synchronise icache and dcache for virtual address range
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_sync_icache)
+    /* check for bad size */
+    PTR_ADDU maxaddr, $a0, $a1
+    blez     $a1, 9f
+
+    /* get synci step and skip if not required */
+    rdhwr    $a2, $1
+    PTR_ADDU maxaddr, -1
+    beqz     $a2, 9f
+
+    /* ensure stores complete */
+    sync
+
+    /* align to line boundaries */
+    PTR_SUBU mask, $a2, 1
+    not      mask
+    and      addr, $a0, mask
+    PTR_SUBU addr, $a2
+    and      maxaddr, mask
+
+  /* the cacheop loop */
+10: PTR_ADDU addr, $a2
+    synci    0(addr)
+    bne      addr, maxaddr, 10b
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_dcache_clean_invalidate (unsigned kva, size_t n)
+ *
+ * Writeback and invalidate address range in data caches
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_dcache_clean_invalidate)
+    SIZE_CACHE($a2, mips_dcache_linesize)
+    vcacheop($a0, $a1, $a2, Hit_Writeback_Inv_D)
+
+9:  lw       $a2, mips_scache_linesize
+    blez     $a2, 9f
+    sync
+    vcacheop($a0, $a1, $a2, Hit_Writeback_Inv_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_dcache_invalidate (unsigned kva, size_t n)
+ *
+ * Invalidate (but don't writeback) address range in data caches
+ * XXX Only safe if region is totally cache-line aligned.
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_dcache_invalidate)
+    SIZE_CACHE($a2, mips_dcache_linesize)
+    vcacheop($a0, $a1, $a2, Hit_Invalidate_D)
+
+9:  lw       $a2, mips_scache_linesize
+    blez     $a2, 9f
+    vcacheop($a0, $a1, $a2, Hit_Invalidate_S)
+
+9:  sync
+    jr.hb    $ra
+
+
+/*
+ * Cache locking
+ *
+ * The MIPS32 cache architecture does support per-line cache locking.
+ *
+ * WARNING: if you lock any cache lines, then don't call the
+ * mips_flush_xcache routines, because these will flush the
+ * locked data out of the cache too; use only mips_clean_xcache.
+ */
+
+/****************************************************************************
+ *
+ * void m32_lock_dcache (void *data, size_t n)
+ *
+ * Load and lock a block of data into the d-cache
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_lock_dcache)
+    SIZE_CACHE($a2, mips_dcache_linesize)
+    vcacheop($a0, $a1, $a2, Fetch_Lock_D)
+    sync
+9:  jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_lock_icache (void *code, size_t n)
+ *
+ * Load and lock a block of instructions into the i-cache
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_lock_icache)
+    SIZE_CACHE($a2, mips_icache_linesize)
+    vcacheop($a0, $a1, $a2, Fetch_Lock_I)
+    sync
+9:  jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_lock_scache (void * data, size_t n)
+ *
+ * Load and lock a block of data into the s-cache
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_lock_scache)
+    SIZE_CACHE($a2, mips_scache_linesize)
+    vcacheop($a0, $a1, $a2, Fetch_Lock_S)
+    sync
+9:  jr.hb    $ra
+
+
+/****************************************************************************
+ *
+ * void m32_dcache_clean (unsigned kva, size_t n)
+ *
+ * Writeback address range in data caches
+ *
+ ****************************************************************************/
+
+FUNCTION(m32_dcache_clean)
+    SIZE_CACHE($a2, mips_dcache_linesize)
+    vcacheop($a0, $a1, $a2, Hit_Writeback_D)
+
+9:  lw       $a2, mips_scache_linesize
+    blez     $a2, 9f
+    vcacheop($a0, $a1, $a2, Hit_Writeback_S)
+
+9:  sync
+    jr.hb    $ra
+
+#endif /* CONFIG_ALLOW_BSD_COMPONENTS */
+
+
diff --git a/boards/mips/jz4780/ci20/configs/net/defconfig 
b/boards/mips/jz4780/ci20/configs/net/defconfig
index 0a033557465..f780e0773f0 100644
--- a/boards/mips/jz4780/ci20/configs/net/defconfig
+++ b/boards/mips/jz4780/ci20/configs/net/defconfig
@@ -15,6 +15,7 @@ CONFIG_16550_UART0_CLOCK=14745600
 CONFIG_16550_UART0_IRQ=51
 CONFIG_16550_UART0_SERIAL_CONSOLE=y
 CONFIG_16550_UART=y
+CONFIG_ALLOW_BSD_COMPONENTS=y
 CONFIG_ARCH="mips"
 CONFIG_ARCH_BOARD="ci20"
 CONFIG_ARCH_BOARD_CI20=y
@@ -40,13 +41,6 @@ CONFIG_FS_PROCFS=y
 CONFIG_GRAN=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_MIPS32_DCACHE=y
-CONFIG_MIPS32_DCACHE_SIZE=32768
-CONFIG_MIPS32_DLINE_SIZE=32
-CONFIG_MIPS32_ICACHE=y
-CONFIG_MIPS32_ICACHE_SIZE=32768
-CONFIG_MIPS32_ILINE_SIZE=32
-CONFIG_MIPS32_KSEG0_IBASE=0x80000000
 CONFIG_MQ_MAXMSGSIZE=64
 CONFIG_NET=y
 CONFIG_NETDEV_IFINDEX=y
diff --git a/boards/mips/jz4780/ci20/configs/nsh/defconfig 
b/boards/mips/jz4780/ci20/configs/nsh/defconfig
index 0832ef1dfd8..4e20accfb6b 100644
--- a/boards/mips/jz4780/ci20/configs/nsh/defconfig
+++ b/boards/mips/jz4780/ci20/configs/nsh/defconfig
@@ -15,6 +15,7 @@ CONFIG_16550_UART0_CLOCK=14745600
 CONFIG_16550_UART0_IRQ=51
 CONFIG_16550_UART0_SERIAL_CONSOLE=y
 CONFIG_16550_UART=y
+CONFIG_ALLOW_BSD_COMPONENTS=y
 CONFIG_ARCH="mips"
 CONFIG_ARCH_BOARD="ci20"
 CONFIG_ARCH_BOARD_CI20=y
@@ -37,13 +38,6 @@ CONFIG_FS_PROCFS=y
 CONFIG_GRAN=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_MIPS32_DCACHE=y
-CONFIG_MIPS32_DCACHE_SIZE=32768
-CONFIG_MIPS32_DLINE_SIZE=32
-CONFIG_MIPS32_ICACHE=y
-CONFIG_MIPS32_ICACHE_SIZE=32768
-CONFIG_MIPS32_ILINE_SIZE=32
-CONFIG_MIPS32_KSEG0_IBASE=0x80000000
 CONFIG_MQ_MAXMSGSIZE=64
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_FILEIOSIZE=512


Reply via email to