diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/TLB.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/TLB.c new file mode 100755 index 000000000..45ce50e3b --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/TLB.c @@ -0,0 +1,56 @@ + + +#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* Invalidate entire unified TLB Inner Shareable */ +#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1) /* Invalidate unified TLB entry by MVA and ASID, Inner Shareable */ +#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2) /* Invalidate unified TLB by ASID match Inner Shareable */ +#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3) /* Invalidate unified TLB entry by MVA all ASID Inner Shareable */ +#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* Invalidate entire instruction TLB. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* Invalidate instruction TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ +#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* Invalidate data TLB by ASID match. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* Invalidate unified TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ + +void InvalidateTlbsAll(void) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, r0, c8, c7, 0\n" /* TLBIALL */ + : + : + : "r0", "memory" + ); +} + +void InvalidateTlbMVA(uint32_t vaddr) +{ + __asm__ __volatile__ + ( + "\tdsb\n" + + "\tmcr p15, 0, %0, c8, c7, 1\n" /* TLBIMVA */ + + "\tdsb\n" + "\tisb\n" + : + : "r" (vaddr) + : "r1", "memory" + ); +} + + +void InvalidateTlbASID(uint32_t vaddr) +{ + __asm__ __volatile__ + ( + "\tdsb\n" + + "\tmcr p15, 0, %0, c8, c7, 2\n" /* TLBIASID */ + + "\tdsb\n" + "\tisb\n" + : + : "r" (vaddr) + : "r1", "memory" + ); +} + + diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/barriers.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/barriers.h new file mode 100644 index 000000000..70e98e5d4 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/barriers.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/barriers.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_BARRIERS_H +#define __ARCH_ARM_SRC_ARMV7_A_BARRIERS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ARMv7-A memory barriers */ + +#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory") +#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory") +#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory") + +#define ARM_DSB() arm_dsb(15) +#define ARM_ISB() arm_isb(15) +#define ARM_DMB() arm_dmb(15) + +#endif /* __ARCH_ARM_SRC_ARMV7_A_BARRIERS_H */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c index 4a71e6c30..6e613f117 100755 --- a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c @@ -1,35 +1,365 @@ -/* -* Copyright (c) 2020 AIIT XUOS Lab -* XiUOS is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. -* You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -* See the Mulan PSL v2 for more details. -*/ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_cache.c + * + * 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. + * + ****************************************************************************/ -/** -* @file: cache.c -* @brief: the general management of system cache -* @version: 3.0 -* @author: AIIT XUOS Lab -* @date: 2023/4/27 -* -*/ +/**************************************************************************** + * Included Files + ****************************************************************************/ -void InvalidInsCache() + +#include "cache.h" +#include "cp15_cacheops.h" +#include "barriers.h" +#include "l1cache.h" +#include "l2cc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +struct ICacheDone { - PlatInvalidInsCache(); + uint32_t (*enable) (void ); + uint32_t (*disable) (void); + uint32_t (*invalidate) (uintptr_t start, uintptr_t end); + uint32_t (*invalidateall) (void ); +}; + +static const struct ICacheDone icache_done = +{ + .enable = enable_icache, + .disable = disable_icache, + .invalidate = invalidate_icache, + .invalidateall = invalidate_icache_all, +}; + + +struct DCacheDone +{ + uint32_t (*enable) (void ); + uint32_t (*disable) (void); + uint32_t (*clean) (uintptr_t start, uintptr_t end); + uint32_t (*flush) (uintptr_t start, uintptr_t end); + uint32_t (*invalidate) (uintptr_t start, uintptr_t end); + uint32_t (*cleanall) (void); + uint32_t (*flushall) (void); + uint32_t (*invalidateall) (void); +}; + +static const struct DCacheDone dcache_done = +{ + .enable = enable_dcache, + .disable = disable_dcache, + .clean = clean_dcache, + .flush = flush_dcache, + .invalidate = invalidate_dcache, + .cleanall = clean_dcache_all, + .flushall = flush_dcache_all, + .invalidateall = invalidate_dcache_all, +}; + + +/**************************************************************************** + * Name: 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 pre-empted. + * + ****************************************************************************/ + +void invalidate_dcache(uintptr_t start, uintptr_t end) +{ + InvalidateL1Dcache(start, end); + InvalidateL2Cache(start, end); } -void InvalidDataCache(unsigned long start, unsigned long end) +/**************************************************************************** + * Name: 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 invalidate_dcache_all(void) { - PlatInvalidDateCache(start, end); + InvalidateL1DcacheAll(); + +#ifdef CONFIG_ARCH_L2CACHE + InvalidateL2CacheAll(); +#endif + } -void CleanDataCache(unsigned long start, unsigned long end) +/**************************************************************************** + * Name: invalidate_icache + * + * Description: + * Invalidate the instruction cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ +void invalidate_icache(uintptr_t start, uintptr_t end) { - PlatCleanDateCache(start, end); -} \ No newline at end of file + InvalidateL1Icache(start, end); +} + +/**************************************************************************** + * Name: invalidate_icache_all + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target + * cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void invalidate_icache_all(void) +{ + InvalidateL1IcacheAll(); +} + +/**************************************************************************** + * Name: 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 pre-empted. + * + ****************************************************************************/ + +void clean_dcache(uintptr_t start, uintptr_t end) +{ + + CleanL1Dcache(start, end); + CleanL2Cache(start, end); +} + +/**************************************************************************** + * Name: 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 pre-empted. + * + ****************************************************************************/ + +void clean_dcache_all(void) +{ + CleanL1DcacheAll(); + CleanL2CacheAll(); +} + +/**************************************************************************** + * Name: 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 pre-empted. + * + ****************************************************************************/ + +void flush_dcache(uintptr_t start, uintptr_t end) +{ + + FlushL1Dcache(start, end); + + + FlushL2Cache(start, end); +} + +/**************************************************************************** + * Name: 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 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 pre-empted. + * + ****************************************************************************/ + +void flush_dcache_all(void) +{ + FlushL1DcacheAll(); + + FlushL2CacheAll(); +} + +/**************************************************************************** + * Name: enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void enable_icache(void) +{ + EnableL1Icache(); +} + +/**************************************************************************** + * Name: disable_icache + * + * Description: + * Disable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void disable_icache(void) +{ + DisableL1Icache(); +} + +/**************************************************************************** + * Name: enable_dcache + * + * Description: + * Enable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void enable_dcache(void) +{ + EnableL1Dcache(); + EnableL2Cache(); +} + +/**************************************************************************** + * Name: disable_dcache + * + * Description: + * Disable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void disable_dcache(void) +{ + DisableL1Dcache(); + DisableL2Cache(); +} + + diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.h new file mode 100644 index 000000000..fb42509fa --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.h @@ -0,0 +1,419 @@ +/**************************************************************************** + * include/nuttx/cache.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_CACHE_H +#define __INCLUDE_NUTTX_CACHE_H + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + + + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Caution: + * The writable global variables aren't initialized yet. + * + ****************************************************************************/ +void enable_icache(void); + + +/**************************************************************************** + * Name: disable_icache + * + * Description: + * Disable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ +void disable_icache(void); + + +/**************************************************************************** + * Name: invalidate_icache + * + * Description: + * Invalidate the instruction cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ +void invalidate_icache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: invalidate_icache_all + * + * Description: + * Invalidate the entire contents of I cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void invalidate_icache_all(void); + +/**************************************************************************** + * Name: lock_icache + * + * Description: + * Prefetch and lock the instruction cache within the specified region. + * If the specified address if not present in the instruction cache, + * some architectures transfer the line from memory, others wait the + * address be read from memory, and then lock. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lock_icache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: unlock_icache + * + * Description: + * Unlock the instruction cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void unlock_icache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: unlock_icache_all + * + * Description: + * Unlock the entire contents of instruction cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void unlock_icache_all(void); + + +/**************************************************************************** + * Name: enable_dcache + * + * Description: + * Enable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Caution: + * The writable global variables aren't initialized yet. + * + ****************************************************************************/ + + +void enable_dcache(void); + + +/**************************************************************************** + * Name: disable_dcache + * + * Description: + * Disable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void disable_dcache(void); + + +/**************************************************************************** + * Name: 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 + * + ****************************************************************************/ + + +void invalidate_dcache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void invalidate_dcache_all(void); + + +/**************************************************************************** + * Name: 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 + * + ****************************************************************************/ + + +void clean_dcache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: clean_dcache_all + * + * Description: + * Clean the entire data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void clean_dcache_all(void); + + +/**************************************************************************** + * Name: 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 + * + ****************************************************************************/ + + +void flush_dcache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: flush_dcache_all + * + * Description: + * Flush the entire data cache by cleaning and invalidating the D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void flush_dcache_all(void); + + +/**************************************************************************** + * Name: lock_dcache + * + * Description: + * Prefetch and lock the data cache within the specified region. + * If the specified address is not present in the data cache, + * some architectures transfer the line from memory, others wait the + * address be read from memory, and then lock. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void lock_dcache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: unlock_dcache + * + * Description: + * Unlock the data cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void unlock_dcache(uintptr_t start, uintptr_t end); + + +/**************************************************************************** + * Name: unlock_dcache_all + * + * Description: + * Unlock the entire contents of data cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + +void unlock_dcache_all(void); + + +/**************************************************************************** + * Name: 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 coherent_dcache(uintptr_t addr, size_t len); + + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __INCLUDE_NUTTX_CACHE_H */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_cacheops.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_cacheops.h new file mode 100644 index 000000000..18fad4d8c --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_cacheops.h @@ -0,0 +1,1141 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_cacheops.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 + * Cortex-A5 which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * 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 NuttX nor Atmel nor the names of the 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 OWNER 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. + * + ****************************************************************************/ + +/* References: + * + * "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright 1996-1998, 2000, 2004-2012 ARM. + * All rights reserved. ARM DDI 0406C.b (ID072512) + */ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H +#define __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Cache definitions ********************************************************/ + +/* L1 Memory */ + +#define CP15_L1_LINESIZE 32 + +/* CP15 Registers ***********************************************************/ + +/* Reference: Cortex-A5 MPCore + * Paragraph 4.1.5, "Cache Operations Registers." + * + * Terms: + * 1) Point of coherency (PoC) + * The PoC is the point at which all agents that can access memory are + * guaranteed to see the same copy of a memory location + * 2) Point of unification (PoU) + * The PoU is the point by which the instruction and data caches and the + * translation table walks of the processor are guaranteed to see the same + * copy of a memory location. + * + * Cache Operations: + * + * CP15 Register: ICIALLUIS + * Description: Invalidate entire instruction cache Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 0 + * CP15 Register: BPIALLIS + * Description: Invalidate entire branch predictor array Inner + * Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 6 + * CP15 Register: ICIALLU + * Description: Invalidate all instruction caches to PoU. Also flushes + * branch target cache. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 0 + * CP15 Register: ICIMVAU + * Description: Invalidate instruction cache by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c5, 1 + * CP15 Register: BPIALL + * Description: Invalidate entire branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 6 + * CP15 Register: BPIMVA + * Description: Invalidate VA from branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 7 + * CP15 Register: DCIMVAC + * Description: Invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c6, 1 + * CP15 Register: DCISW + * Description: Invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c6, 2 + * CP15 Register: DCCMVAC + * Description: Clean data cache line to PoC by VA. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c10, 1 + * CP15 Register: DCCSW + * Description: Clean data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c10, 2 + * CP15 Register: DCCMVAU + * Description: Clean data or unified cache line by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c11, 1 + * CP15 Register: DCCIMVAC + * Description: Clean and invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c14, 1 + * CP15 Register: DCCISW + * Description: Clean and invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c14, 2 + */ + +/* Set/way format */ + +#define CACHE_WAY_SHIFT (3) /* Bits 30-31: Way in set being accessed */ +#define CACHE_WAY_MASK (3 << CACHE_WAY_SHIFT) +#define CACHE_SET_SHIFT (5) /* Bits 5-(S+4): Way in set being accessed */ + /* For 4KB cache size: S=5 */ +#define CACHE_SET4KB_MASK (0x1f << CACHE_SET_SHIFT) + /* Bits 10-29: Reserved */ + /* For 8KB cache size: S=6 */ +#define CACHE_SET8KB_MASK (0x3f << CACHE_SET_SHIFT) + /* Bits 11-29: Reserved */ + /* For 16KB cache size: S=7 */ +#define CACHE_SET16KB_MASK (0x7f << CACHE_SET_SHIFT) + /* Bits 12-29: Reserved */ + /* For 32KB cache size: S=8 */ +#define CACHE_SET32KB_MASK (0xff << CACHE_SET_SHIFT) + /* Bits 13-29: Reserved */ + /* For 64KB cache size: S=9 */ +#define CACHE_SET64KB_MASK (0x1fff << CACHE_SET_SHIFT) + /* Bits 14-29: Reserved */ + +/* VA and SBZ format */ + +#define CACHE_SBZ_SHIFT (4) /* Bits 0-4: Should be zero (SBZ) */ +#define CACHE_SBZ_MASK (31 << TLB_SBZ_SHIFT) +#define CACHE_VA_MASK (0xfffffffe0) /* Bits 5-31: Virtual address */ + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/* cp15_cache Cache Operations + * + * Usage + * + * They are performed as MCR instructions and only operate on a level 1 cache + * associated with ARM v7 processor. + * + * The supported operations are: + * + * 1. Any of these operations can be applied to any data cache or any + * unified cache. + * 2. Invalidate by MVA. Performs an invalidate of a data or unified cache + * line + * based on the address it contains. + * 3. Invalidate by set/way. Performs an invalidate of a data or unified + * cache line based on its location in the cache hierarchy. + * 4. Clean by MVA. Performs a clean of a data or unified cache line based + * on the address it contains. + * 5. Clean by set/way. Performs a clean of a data or unified cache line + * based on its location in the cache hierarchy. + * 6. Clean and Invalidate by MVA. Performs a clean and invalidate of a + * data or unified cache line based on the address it contains. + * 7. Clean and Invalidate by set/way. Performs a clean and invalidate of + * a data or unified cache line based on its location in the cache + * hierarchy. + * + * NOTE: Many of these operations are implemented as assembly language + * macros or as C inline functions in the file cache.h. The larger functions + * are implemented here as C-callable functions. + */ + +#ifdef __ASSEMBLY__ + +/**************************************************************************** + * Name: cp15_enable_dcache + * + * Description: + * Enable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_enable_dcache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + orr \tmp, \tmp, #(0x1 << 2) /* Enable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ +.endm + +/**************************************************************************** + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_disable_dcache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ +.endm + +/**************************************************************************** + * Name: cp15_enable_icache + * + * Description: + * Enable L1 I Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_enable_icache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + orr \tmp, \tmp, #(0x1 << 12) /* Enable I cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ +.endm + +/**************************************************************************** + * Name: cp15_disable_icache + * + * Description: + * Disable L1 I Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_disable_icache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 12) /* Disable I cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner shareable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_icache_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 0 /* ICIALLUIS */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner shareable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_btb_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 6 /* BPIALLIS */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target + * cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_icache, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 0 /* ICIALLU */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_icache_bymva, va + mrc p15, 0, \va, c7, c5, 1 /* ICIMVAU */ +.endm + +/**************************************************************************** + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_flush_btb, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 6 /* BPIALL */ +.endm + +/**************************************************************************** + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_flush_btb_bymva, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 7 /* BPIMVA */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c6, 1 /* DCIMVAC */ +.endm + +/**************************************************************************** + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_invalidate_dcacheline_bysetway, setway + mrc p15, 0, \setway, c7, c6, 2 /* DCISW */ +.endm + +/**************************************************************************** + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_clean_dcache_bymva, va + mrc p15, 0, \va, c7, c10, 1 /* DCCMVAC */ +.endm + +/**************************************************************************** + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_clean_dcache_bysetway, setway + mrc p15, 0, \setway, c7, c10, 2 /* DCCSW */ +.endm + +/**************************************************************************** + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - Register with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_clean_ucache_bymva, setway + mrc p15, 0, \setway, c7, c11, 1 /* DCCMVAU */ +.endm + +/**************************************************************************** + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_cleaninvalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c14, 1 /* DCCIMVAC */ +.endm + +/**************************************************************************** + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +.macro cp15_cleaninvalidate_dcacheline, setway + mrc p15, 0, \setway, c7, c14, 2 /* DCCISW */ +.endm + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: cp15_enable_dcache + * + * Description: + * Enable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_enable_dcache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\torr r0, r0, #(1 << 2)\n" /* Enable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_disable_dcache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_enable_icache + * + * Description: + * Enable L1 I Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_enable_icache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\torr r0, r0, #(1 << 12)\n" /* Enable I cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_disable_icache + * + * Description: + * Disable L1 I Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_disable_icache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 12)\n" /* Disable I cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner shareable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_invalidate_icache_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 0\n" /* ICIALLUIS */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner shareable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_invalidate_btb_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 6\n" /* BPIALLIS */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target + * cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_invalidate_icache(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 0\n" /* ICIALLU */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_invalidate_icache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c5, 1\n" /* ICIMVAU */ + : + : "r" (va) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_flush_btb(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 6\n" /* BPIALL */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_flush_btb_bymva(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 7\n" /* BPIMVA */ + : + : + : "r0", "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +/* Invalidate data cache line by VA to PoC */ + +static inline void cp15_invalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 1\n" /* DCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +/* Invalidate data cache line by set/way */ + +static inline void cp15_invalidate_dcacheline_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 2\n" /* DCISW */ + : + : "r" (setway) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +/* Clean data cache line by MVA */ + +static inline void cp15_clean_dcache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 1\n" /* DCCMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_clean_dcache_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 2\n" /* DCCSW */ + : + : "r" (setway) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - 32-bit value with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_clean_ucache_bymva(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c11, 1\n" /* DCCMVAU */ + : + : "r" (setway) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, r0, c7, c14, 1\n" /* DCCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c14, 2\n" /* DCCISW */ + : + : "r" (setway) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: cp15_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: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_coherent_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_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 + * + ****************************************************************************/ + +void cp15_invalidate_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_invalidate_dcache_all(void); + +/**************************************************************************** + * Name: cp15_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 + * + ****************************************************************************/ + +void cp15_clean_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_clean_dcache_all + * + * Description: + * Clean the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_clean_dcache_all(void); + +/**************************************************************************** + * Name: cp15_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 + * + ****************************************************************************/ + +void cp15_flush_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_flush_dcache_all + * + * Description: + * Flush the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_flush_dcache_all(void); + +/**************************************************************************** + * Name: cp15_cache_size + * + * Description: + * Get cp15 cache size in byte + * + * Input Parameters: + * None + * + * Returned Value: + * Cache size in byte + * + ****************************************************************************/ + +uint32_t cp15_cache_size(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_coherent_dcache.S b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_coherent_dcache.S new file mode 100644 index 000000000..88c5feb4c --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cp15_coherent_dcache.S @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_coherent_dcache.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 + * Cortex-A5 which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * 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 NuttX nor Atmel nor the names of the 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 OWNER 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. + * + ****************************************************************************/ + +/* References: + * + * "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_coherent_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_coherent_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_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: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_coherent_dcache + .type cp15_coherent_dcache, function + +cp15_coherent_dcache: + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, flushing each D cache line to memory */ +1: + mcr CP15_DCCMVAU(r12) /* Clean data or unified cache line by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + and r3, r3, #0xf /* Isolate the IminLine field */ + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, invalidating each I cache line to memory */ +1: + mcr CP15_ICIMVAU(r12) /* Invalidate instruction cache by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been invalidated */ + blo 1b + + mov r0, #0 + mcr CP15_BPIALLIS(r0) /* Invalidate entire branch predictor array Inner Shareable */ + mcr CP15_BPIALL(r0) /* Invalidate entire branch predictor array Inner Shareable */ + + dsb + isb + bx lr + .size cp15_coherent_dcache, . - cp15_coherent_dcache + .end diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.c new file mode 100644 index 000000000..2e2be4d97 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.c @@ -0,0 +1,279 @@ +#include "l1cache.h" +#include "cp15_cacheops.h" +#include "barriers.h" + +void InvalidateL1Dcache(uintptr_t start, uintptr_t end) +{ + size_t length=end-start; + void* addr=start; + + uint32_t va; + uint32_t csidr = 0, line_size = 0; + + // get the cache line size + _ARM_MRC(15, 1, csidr, 0, 0, 0); + line_size = 1 << ((csidr & 0x7) + 4); + + // align the address with line + const void * end_addr = (const void *)((uint32_t)addr + length); + + do + { + // Clean data cache line to PoC (Point of Coherence) by va. + va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK + _ARM_MCR(15, 0, va, 7, 6, 1); + // increment addres to next line and decrement lenght + addr = (const void *) ((uint32_t)addr + line_size); + } while (addr < end_addr); + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + +void InvalidateL1DcacheAll(void) +{ + uint32_t csid; // Cache Size ID + uint32_t wayset; // wayset parameter + int num_sets; // number of sets + int num_ways; // number of ways + + _ARM_MRC(15, 1, csid, 0, 0, 0); // Read Cache Size ID + + // Fill number of sets and number of ways from csid register This walues are decremented by 1 + num_ways = (csid >> 0x03) & 0x3FFu; //((csid& csid_ASSOCIATIVITY_MASK) >> csid_ASSOCIATIVITY_SHIFT) + + // Invalidation all lines (all Sets in all ways) + while (num_ways >= 0) + { + num_sets = (csid >> 0x0D) & 0x7FFFu; //((csid & csid_NUMSETS_MASK) >> csid_NUMSETS_SHIFT) + while (num_sets >= 0 ) + { + wayset = (num_sets << 5u) | (num_ways << 30u); //(num_sets << SETWAY_SET_SHIFT) | (num_sets << 3SETWAY_WAY_SHIFT) + // invalidate line if we know set and way + _ARM_MCR(15, 0, wayset, 7, 6, 2); + num_sets--; + } + num_ways--; + } + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + + +void CleanL1Dcache(uintptr_t start, uintptr_t end) +{ + void* addr=start; + size_t length=end-start; + uint32_t va; + uint32_t csidr = 0, line_size = 0; + const void * end_addr = (const void *)((uint32_t)addr + length); + + // get the cache line size + _ARM_MRC(15, 1, csidr, 0, 0, 0); + line_size = 1 << ((csidr & 0x7) + 4); + + do + { + // Clean data cache line to PoC (Point of Coherence) by va. + va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK + _ARM_MCR(15, 0, va, 7, 10, 1); + + // increment addres to next line and decrement lenght + addr = (const void *) ((uint32_t)addr + line_size); + } while (addr < end_addr); + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + +void CleanL1DcacheAll(void) +{ + uint32_t csid; // Cache Size ID + uint32_t wayset; // wayset parameter + int num_sets; // number of sets + int num_ways; // number of ways + + _ARM_MRC(15, 1, csid, 0, 0, 0); // Read Cache Size ID + + // Fill number of sets and number of ways from csid register This walues are decremented by 1 + num_ways = (csid >> 0x03) & 0x3FFu; //((csid& csid_ASSOCIATIVITY_MASK) >> csid_ASSOCIATIVITY_SHIFT`) + while (num_ways >= 0) + { + num_sets = (csid >> 0x0D) & 0x7FFFu; //((csid & csid_NUMSETS_MASK) >> csid_NUMSETS_SHIFT ) + while (num_sets >= 0 ) + { + wayset = (num_sets << 5u) | (num_ways << 30u); //(num_sets << SETWAY_SET_SHIFT) | (num_ways << 3SETWAY_WAY_SHIFT) + // FLUSH (clean) line if we know set and way + _ARM_MCR(15, 0, wayset, 7, 10, 2); + num_sets--; + } + num_ways--; + } + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + +void FlushL1Dcache(uintptr_t start, uintptr_t end) +{ + void* addr=start; + size_t length=end-start; + uint32_t va; + uint32_t csidr = 0, line_size = 0; + const void * end_addr = (const void *)((uint32_t)end); + + // get the cache line size + _ARM_MRC(15, 1, csidr, 0, 0, 0); + line_size = 1 << ((csidr & 0x7) + 4); + + do + { + // Clean data cache line to PoC (Point of Coherence) by va. + va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK + _ARM_MCR(15, 0, va, 7, 14, 1); + + // increment addres to next line and decrement lenght + addr = (const void *) ((uint32_t)addr + line_size); + } while (addr < end_addr); + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + +void FlushL1DcacheAll(void) +{ + uint32_t csid; // Cache Size ID + uint32_t wayset; // wayset parameter + int num_sets; // number of sets + int num_ways; // number of ways + + _ARM_MRC(15, 1, csid, 0, 0, 0); // Read Cache Size ID + + // Fill number of sets and number of ways from csid register This walues are decremented by 1 + num_ways = (csid >> 0x03) & 0x3FFu; //((csid& csid_ASSOCIATIVITY_MASK) >> csid_ASSOCIATIVITY_SHIFT`) + while (num_ways >= 0) + { + num_sets = (csid >> 0x0D) & 0x7FFFu; //((csid & csid_NUMSETS_MASK) >> csid_NUMSETS_SHIFT ) + while (num_sets >= 0 ) + { + wayset = (num_sets << 5u) | (num_ways << 30u); //(num_sets << SETWAY_SET_SHIFT) | (num_ways << 3SETWAY_WAY_SHIFT) + // FLUSH (clean) line if we know set and way + _ARM_MCR(15, 0, wayset, 7, 14, 2); + num_sets--; + } + num_ways--; + } + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} + +void InvalidateL1IcacheAll() +{ + uint32_t SBZ = 0x0u; + + _ARM_MCR(15, 0, SBZ, 7, 5, 0); + + // synchronize context on this processor + _ARM_ISB(); +} + +void InvalidateL1Icache(uintptr_t start, uintptr_t end) +{ + void* addr=start; + uint32_t va; + uint32_t csidr = 0, line_size = 0; + const void * end_addr = (const void *)((uint32_t)end); + + // get the cache line size + _ARM_MRC(15, 1, csidr, 0, 0, 0); + line_size = 1 << ((csidr & 0x7) + 4); + + do + { + // Clean data cache line to PoC (Point of Coherence) by va. + va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK + _ARM_MCR(15, 0, va, 7, 5, 1); + // increment addres to next line and decrement lenght + addr = (const void *) ((uint32_t)addr + line_size); + } while (addr < end_addr); + + // synchronize context on this processor + _ARM_ISB(); +} + +void EnableL1Icache(void) +{ + uint32_t sctlr ;// System Control Register + + // read sctlr + _ARM_MRC(15, 0, sctlr, 1, 0, 0); + + // ignore the operation if I is enabled already + if(!(sctlr & BM_SCTLR_I)) + { + // set I bit (instruction caching enable) + sctlr |= BM_SCTLR_I; + + // write modified sctlr + _ARM_MCR(15, 0, sctlr, 1, 0, 0); + + // synchronize context on this processor + _ARM_ISB(); + } +} + +void DisableL1Icache() +{ + uint32_t sctlr ;// System Control Register + + // read sctlr + _ARM_MRC(15, 0, sctlr, 1, 0, 0); + + // Clear I bit (instruction caching enable) + sctlr &= ~BM_SCTLR_I; + + // write modified sctlr + _ARM_MCR(15, 0, sctlr, 1, 0, 0); + + // synchronize context on this processor + _ARM_ISB(); +} + +void EnableL1Dcache() +{ + uint32_t sctlr; // System Control Register + + // read sctlr + _ARM_MRC(15, 0, sctlr, 1, 0, 0); + + if (!(sctlr & BM_SCTLR_C)) + { + // set C bit (data caching enable) + sctlr |= BM_SCTLR_C; + + // write modified sctlr + _ARM_MCR(15, 0, sctlr, 1, 0, 0); + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); + } +} + +void DisableL1Dcache() +{ + uint32_t sctlr; // System Control Register + + // read sctlr + _ARM_MRC(15, 0, sctlr, 1, 0, 0); + + // set C bit (data caching enable) + sctlr &= ~BM_SCTLR_C; + + // write modified sctlr + _ARM_MCR(15, 0, sctlr, 1, 0, 0); + + // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + _ARM_DSB(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.h new file mode 100644 index 000000000..757157cae --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l1cache.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file l1cache.c + * @brief PLC inovance am401 app + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2023.8.10 + */ + +#include +#include +#include "cortex_a9.h" + +/* Terms: + * 1) Point of coherency (PoC) + * The PoC is the point at which all agents that can access memory are + * guaranteed to see the same copy of a memory location + * 2) Point of unification (PoU) + * The PoU is the point by which the instruction and data caches and the + * translation table walks of the processor are guaranteed to see the same + * copy of a memory location. + * + * L1 Cache Operations: + * + * CP15 Register: ICIALLUIS + * Description: Invalidate entire instruction cache Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 0 + * CP15 Register: BPIALLIS + * Description: Invalidate entire branch predictor array Inner + * Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 6 + * CP15 Register: ICIALLU + * Description: Invalidate all instruction caches to PoU. Also flushes + * branch target cache. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 0 + * CP15 Register: ICIMVAU + * Description: Invalidate instruction cache by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c5, 1 + * CP15 Register: CP15ISB + * Description: Instruction Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c5, 4 + * CP15 Register: BPIALL + * Description: Invalidate entire branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 6 + * CP15 Register: BPIMVA + * Description: Invalidate VA from branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 7 + * CP15 Register: DCIMVAC + * Description: Invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c6, 1 + * CP15 Register: DCISW + * Description: Invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c6, 2 + * CP15 Register: DCCMVAC + * Description: Clean data cache line to PoC by VA. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c10, 1 + * CP15 Register: DCCSW + * Description: Clean data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c10, 2 + * CP15 Register: CP15DSB + * Description: Data Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 4 + * CP15 Register: CP15DMB + * Description: Data Memory Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 5 + * CP15 Register: DCCMVAU + * Description: Clean data or unified cache line by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c11, 1 + * CP15 Register: DCCIMVAC + * Description: Clean and invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c14, 1 + * CP15 Register: DCCISW + * Description: Clean and invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c14, 2 + */ + +#define BM_SCTLR_I (1 << 12) //!< Instruction cache enable +#define BM_SCTLR_C (1 << 2) //!< Data cache enable + +void InvalidateL1Dcache(uintptr_t start, uintptr_t end); + +void InvalidateL1DcacheAll(void); + + +void CleanL1Dcache(uintptr_t start, uintptr_t end); + +void CleanL1DcacheAll(void); + +void FlushL1Dcache(uintptr_t start, uintptr_t end); + +void FlushL1DcacheAll(void); + + +void InvalidateL1IcacheAll(void); + +void InvalidateL1Icache(uintptr_t start, uintptr_t end); + +void EnableL1Icache(void); +void DisableL1Icache(); + +void EnableL1Dcache(); + +void DisableL1Dcache(); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc.h new file mode 100644 index 000000000..5b858e3a3 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/l2cc.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_L2CC_H +#define __ARCH_ARM_SRC_ARMV7_A_L2CC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define CONFIG_ARCH_L2CACHE + +#ifdef CONFIG_ARCH_L2CACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if 0 /* Prototyped in arm_internal.h */ +void arm_l2ccinitialize(void); +#endif + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void EnableL2Cache(void); + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2 cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void DisableL2Cache(void); + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void SyncL2Cache(void); + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void InvalidateL2CacheAll(void); + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses in the L2 cache + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void InvalidateL2Cache(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void CleanL2CacheAll(void); + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void CleanL2Cache(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void FlushL2CacheAll(void); + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void FlushL2Cache(uint32_t startaddr, uint32_t endaddr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_ARCH_L2CACHE */ + /* Provide simple definitions to concentrate the inline conditional + * compilation in one place. + */ + +# define EnableL2Cache() +# define DisableL2Cache() +# define SyncL2Cache() +# define InvalidateL2CacheAll() +# define InvalidateL2Cache(s,e) +# define CleanL2CacheAll() +# define CleanL2Cache(s,e) +# define FlushL2CacheAll() +# define FlushL2Cache(s,e) + +#endif /* CONFIG_ARCH_L2CACHE */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_L2CC_H */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.c new file mode 100644 index 000000000..0bc4712a1 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.c @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file l2cc_pl310.c + * @brief PLC inovance am401 app + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2023.8.10 + */ + + + +#include +#include +#include + + +#include "l2cc.h" +#include "l2cc_pl310.h" + + +#define CONFIG_ARMV7A_ASSOCIATIVITY_8WAY +#define CONFIG_ARMV7A_WAYSIZE_16KB + +#define getreg8(a) (*(volatile uint8_t *)(a)) +#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +#define getreg16(a) (*(volatile uint16_t *)(a)) +#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +#define getreg32(a) (*(volatile uint32_t *)(a)) +#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +#ifdef CONFIG_HAVE_FILENAME +# define PANIC() _assert(__FILE__, __LINE__) +#else +# define PANIC() _assert("unknown", 0) +#endif + +#define ASSERT(f) do { if (!(f)) PANIC(); } while (0) +#define VERIFY(f) do { if ((f) < 0) PANIC(); } while (0) + +#ifdef CONFIG_DEBUG_ASSERTIONS +# define DEBUGPANIC() PANIC() +# define DEBUGASSERT(f) ASSERT(f) +# define DEBUGVERIFY(f) VERIFY(f) +#else +# define DEBUGPANIC() +# define DEBUGASSERT(f) ((void)(1 || (f))) +# define DEBUGVERIFY(f) ((void)(f)) +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Number of ways depends on ARM configuration */ + +#if defined(CONFIG_ARMV7A_ASSOCIATIVITY_8WAY) +# define PL310_NWAYS 8 +# define PL310_WAY_MASK 0x000000ff +#elif defined(CONFIG_ARMV7A_ASSOCIATIVITY_16WAY) +# define PL310_NWAYS 16 +# define PL310_WAY_MASK 0x0000ffff +#else +# error "Number of ways not selected" +#endif + +/* The size of one depends on ARM configuration */ + +#if defined(CONFIG_ARMV7A_WAYSIZE_16KB) +# define PL310_WAYSIZE (16 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_32KB) +# define PL310_WAYSIZE (32 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_64KB) +# define PL310_WAYSIZE (64 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_128KB) +# define PL310_WAYSIZE (128 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_256KB) +# define PL310_WAYSIZE (256 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_512KB) +# define PL310_WAYSIZE (512 * 1024) +#else +# error "Way size not selected" +#endif + +/* The size of the cache is then the product of the number of ways times + * the size of each way. + */ + +#define PL310_CACHE_SIZE (PL310_NWAYS * PL310_WAYSIZE) + +/* Use for aligning addresses to a cache line boundary */ + +#define PL310_CACHE_LINE_MASK (PL310_CACHE_LINE_SIZE - 1) + +/* Configurable options + * + * REVISIT: Currently there are not configuration options. All values + * are just set to the default. + */ + +/* Bit 0: Full line zero enable + * + * Default: 0=Full line of write zero behavior disabled + */ + +#define L2CC_ACR_FLZE_CONFIG (0) /* 0=Full line of write zero behavior disabled */ + +/* Bit 10: High Priority for SO and Dev Reads Enable + * + * Default: 0=Strongly Ordered and Device reads have lower priority than + * cacheable accesses + */ + +#define L2CC_ACR_HPSO_CONFIG (0) /* 0=Have lower priority than cache */ + +/* Bit 11: Store Buffer Device Limitation Enable + * + * Default: 0=Store buffer device limitation disabled + */ + +#define L2CC_ACR_SBDLE_CONFIG (0) /* 0=Store buffer device limitation disabled */ + +/* Bit 12: Exclusive Cache Configuration + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EXCC_CONFIG (0) /* 0=Disabled */ + +/* Bit 13: Shared Attribute Invalidate Enable + * + * Default: 0=Shared invalidate behavior disabled + */ + +#define L2CC_ACR_SAIE_CONFIG (0) /* 0=Shared invalidate behavior disabled */ + +/* Bit 20: Event Monitor Bus Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EMBEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 21: Parity Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_PEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 22: Shared Attribute Override Enable + * + * Default: 0=Treats shared accesses as specified in the TRM + */ + +#define L2CC_ACR_SAOEN_CONFIG (0) /* 0=As specified in the TRM */ + +/* Bits 23-24: Force Write Allocate + * + * Default: 0=Use AWCACHE attributes for WA + */ + +#define L2CC_ACR_FWA_CONFIG L2CC_ACR_FWA_AWCACHE /* Use AWCACHE attributes for WA */ + +/* Bit 25: Cache Replacement Policy + * + * Default: 1=Round robin replacement policy + */ + +#define L2CC_ACR_CRPOL_CONFIG L2CC_ACR_CRPOL /* 1=Round robin replacement policy */ + +/* Bit 26: Non-Secure Lockdown Enable + * + * Default: 0=Lockdown registers cannot be modified using non-secure accesses + */ + +#define L2CC_ACR_NSLEN_CONFIG (0) /* 0=Secure access only */ + +/* Bit 27: Non-Secure Interrupt Access Control + * + * Default: 0=Interrupt Clear and Mask can only be modified or read with + * secure accesses + */ + +#define L2CC_ACR_NSIAC_CONFIG (0) /* 0=Secure access only */ + +/* Bit 28: Data Prefetch Enable + * + * Default: 0=Data prefetching disabled + */ + +#define L2CC_ACR_DPEN_CONFIG (0) /* 0=Data prefetching disabled */ + +/* Bit 29: Instruction Prefetch Enable + * + * Default: 0=Instruction prefetching disabled + */ + +#define L2CC_ACR_IPEN_CONFIG (0) /* 0=Instruction prefetching disabled */ + +/* Bit 30: Early BRESP enable + * + * Default: 0=Early BRESP disabled + */ + +#define L2CC_ACR_EBRESP_CONFIG (0) /* 0=Early BRESP disabled */ + +#define L2CC_ACR_CONFIG \ + (L2CC_ACR_FLZE_CONFIG | L2CC_ACR_HPSO_CONFIG | L2CC_ACR_SBDLE_CONFIG | \ + L2CC_ACR_EXCC_CONFIG | L2CC_ACR_SAIE_CONFIG | L2CC_ACR_EMBEN_CONFIG | \ + L2CC_ACR_PEN_CONFIG | L2CC_ACR_SAOEN_CONFIG | L2CC_ACR_FWA_CONFIG | \ + L2CC_ACR_CRPOL_CONFIG | L2CC_ACR_NSLEN_CONFIG | L2CC_ACR_NSIAC_CONFIG | \ + L2CC_ACR_DPEN_CONFIG | L2CC_ACR_IPEN_CONFIG | L2CC_ACR_EBRESP_CONFIG) + +#define L2CC_ACR_ALLCONFIGS (0x7f303c01) +#define L2CC_ACR_CONFIGMASK (L2CC_ACR_SBZ | L2CC_ACR_ALLCONFIGS) + +/* Filter end address */ + +#define CONFIG_PL310_FLEND (CONFIG_PL310_FLSTRT + CONFIG_PL310_FLSIZE) + +/* Block size. Used to break up long operations so that interrupts are not + * disabled for a long time. + */ + +#define PL310_GULP_SIZE 4096 + +/* Misc commoly defined and re-defined things */ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef OK +# define OK 0 +#endif + +/* Data synchronization barrier */ + +#define dsb(a) __asm__ __volatile__ ("dsb " #a : : : "memory") + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pl310_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pl310_flush_all(void) +{ + /* Flush all ways by writing the set of ways to be cleaned to the Clean + * Invalidate Way Register (CIWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_CIWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CIWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_l2ccinitialize(void) +{ + uint32_t regval; + int i; + + /* Make sure that this is a PL310 cache, version r3p2. + * + * REVISIT: The SAMA5D4 is supposed to report its ID as 0x410000C8 which + * is r3p2, but the chip that I have actually* reports 0x410000C9 which + * is some later revision. + */ + + /* DEBUGASSERT((getreg32(L2CC_IDR) & L2CC_IDR_REV_MASK) == + * L2CC_IDR_REV_R3P2); + */ + + /* Make sure that actual cache configuration agrees with the configured + * cache configuration. + */ + +#if defined(CONFIG_ARMV7A_ASSOCIATIVITY_8WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 0); +#elif defined(CONFIG_ARMV7A_ASSOCIATIVITY_16WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == L2CC_ACR_ASS); +#else +# error No associativity selected +#endif + +#if defined(CONFIG_ARMV7A_WAYSIZE_16KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_16KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_32KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_32KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_64KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_64KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_128KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_128KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_256KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_256KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_512KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == + L2CC_ACR_WAYSIZE_512KB); +#else +# error No way size selected +#endif + + /* L2 configuration can only be changed if the cache is disabled, + * + * NOTE: This register access will fail if we are not in secure more. + */ + + if ((getreg32(L2CC_CR) & L2CC_CR_L2CEN) == 0) + { +#if defined(CONFIG_PL310_TRCR_TSETLAT) && defined(CONFIG_PL310_TRCR_TRDLAT) && \ + defined(CONFIG_PL310_TRCR_TWRLAT) + /* Configure Tag RAM control */ + + regval = ((CONFIG_PL310_TRCR_TSETLAT - 1) << L2CC_TRCR_TSETLAT_SHIFT) + ((CONFIG_PL310_TRCR_TRDLAT - 1) << L2CC_TRCR_TRDLAT_SHIFT) | + ((CONFIG_PL310_TRCR_TWRLAT - 1) << L2CC_TRCR_TWRLAT_SHIFT); + putreg32(regval, L2CC_TRCR); +#endif + +#if defined(CONFIG_PL310_DRCR_DSETLAT) && defined(CONFIG_PL310_DRCR_DRDLAT) && \ + defined(CONFIG_PL310_DRCR_DWRLAT) + /* Configure Data RAM control */ + + regval = ((CONFIG_PL310_DRCR_DSETLAT - 1) << L2CC_DRCR_DSETLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DRDLAT - 1) << L2CC_DRCR_DRDLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DWRLAT - 1) << L2CC_DRCR_DWRLAT_SHIFT); + putreg32(regval, L2CC_DRCR); +#endif + +#ifdef PL310_ADDRESS_FILTERING +#if defined(CONFIG_PL310_FLSTRT) && defined(CONFIG_PL310_FLSIZE) + /* Configure the address filter */ + + regval = (CONFIG_PL310_FLEND + ~L2CC_FLEND_MASK) & L2CC_FLEND_MASK; + putreg32(regval, L2CC_FLEND); + + regval = (CONFIG_PL310_FLSTRT & L2CC_FLSTRT_MASK) | L2CC_FLSTRT_ENABLE; + putreg32(regval | L2X0_ADDR_FILTER_EN, L2CC_FLSTRT); +#endif +#endif + + /* Make sure that the memory is not locked down */ + + for (i = 0; i < PL310_NLOCKREGS; i++) + { + putreg32(0, L2CC_DLKR(i)); + putreg32(0, L2CC_ILKR(i)); + } + + /* Configure the cache properties */ + + regval = getreg32(L2CC_ACR); + regval &= ~L2CC_ACR_CONFIGMASK; + regval |= L2CC_ACR_CONFIG; + putreg32(regval, L2CC_ACR); + + /* Invalidate and enable the cache */ + + InvalidateL2CacheAll(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + } + + sinfo("(%d ways) * (%d bytes/way) = %d bytes\n", + PL310_NWAYS, PL310_WAYSIZE, PL310_CACHE_SIZE); +} + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void EnableL2Cache(void) +{ + /* Invalidate and enable the cache (must be disabled to do this!) */ + InvalidateL2CacheAll(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + +} + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void DisableL2Cache(void) +{ + + pl310_flush_all(); + + /* Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) */ + + putreg32(0, L2CC_CR); + dsb(); + +} + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void SyncL2Cache(void) +{ + + putreg32(0, L2CC_CSR); + +} + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate all ways using the Invalidate Way Register (IWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void InvalidateL2CacheAll(void) +{ + + uint32_t regval; + + /* Invalidate all ways */ + + + /* Disable the L2 cache while we invalidate it */ + + regval = getreg32(L2CC_CR); + DisableL2Cache(); + + /* Invalidate all ways by writing the bit mask of ways to be invalidated + * the Invalidate Way Register (IWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_IWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_IWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + + /* Then re-enable the L2 cache if it was enabled before */ + + putreg32(regval, L2CC_CR); + +} + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses by writing to the Invalidate Physical + * Address Line Register (IPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void InvalidateL2Cache(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t invalsize; + uintptr_t gulpend; + + + /* Check if the start address is aligned with a cacheline */ + + + if ((startaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush the cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(startaddr, L2CC_CIPALR); + + /* Then start invalidating at the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Check if the end address is aligned with a cache line */ + + if ((endaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + endaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(endaddr, L2CC_CIPALR); + } + + + + /* Loop, invalidated the address range by cache line. Interrupts are re- + * enabled momentarily every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to invalidate. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + invalsize = endaddr - startaddr; + gulpend = startaddr + MIN(invalsize, PL310_GULP_SIZE); + + /* Disable interrupts and invalidate the gulp */ + + + while (startaddr < gulpend) + { + /* Invalidate the cache line by writing the address to the + * Invalidate Physical Address Line Register (IPALR). + */ + + putreg32(startaddr, L2CC_IPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + + putreg32(0, L2CC_CSR); + +} + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean all ways by using the Clean Ways Register (CWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void CleanL2CacheAll(void) +{ + + + + putreg32(PL310_WAY_MASK, L2CC_CWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + +} + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean the cache line over a range of addresses uing the Clean Physical + * Address Line Register (CPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void CleanL2Cache(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t cleansize; + uintptr_t gulpend; + + + /* If the range of addresses to clean is as large or larger the L2 cache, + * then just clean the whole thing. + */ + + cleansize = endaddr - startaddr; + if (cleansize >= PL310_CACHE_SIZE) + { + CleanL2CacheAll(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Clean the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + cleansize = endaddr - startaddr; + gulpend = startaddr + MIN(cleansize, PL310_GULP_SIZE); + + /* Disable interrupts and clean the gulp */ + + + while (startaddr < gulpend) + { + /* Clean the cache line by writing the address to the Clean + * Physical Address Line Register (CPALR). + */ + + putreg32(startaddr, L2CC_CPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + + putreg32(0, L2CC_CSR); + +} + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void FlushL2CacheAll(void) +{ + + + /* Flush all ways using the Clean Invalidate Way Register (CIWR). */ + + + pl310_flush_all(); + +} + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address by using the Clean Invalidate Physical Address + * Line Register (CIPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void FlushL2Cache(uint32_t startaddr, uint32_t endaddr) +{ + uintptr_t flushsize; + uintptr_t gulpend; + + + /* If the range of addresses to flush is as large or larger the L2 cache, + * then just flush the whole thing. + */ + + flushsize = endaddr - startaddr; + if (flushsize >= PL310_CACHE_SIZE) + { + l2cc_flush_all(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Flush the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + flushsize = endaddr - startaddr; + gulpend = startaddr + MIN(flushsize, PL310_GULP_SIZE); + + /* Disable interrupts and flush the gulp */ + + + while (startaddr < gulpend) + { + /* Flush the cache line by writing the address to the Clean + * Invalidate Physical Address Line Register (CIPALR). + */ + + putreg32(startaddr, L2CC_CIPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + + putreg32(0, L2CC_CSR); + +} + + diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.h new file mode 100644 index 000000000..e5c5c1225 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/l2cc_pl310.h @@ -0,0 +1,483 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/l2cc_pl310.h + * + * 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. + * + ****************************************************************************/ + +/* Reference: "CoreLink� Level 2 Cache Controller L2C-310", Revision r3p2, + * Technical Reference Manual, ARM DDI 0246F (ID011711), ARM + */ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H +#define __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* General Definitions ******************************************************/ + +#define PL310_CACHE_LINE_SIZE 32 + +#ifdef CONFIG_PL310_LOCKDOWN_BY_MASTER +# define PL310_NLOCKREGS 8 +#else +# define PL310_NLOCKREGS 1 +#endif + +/* L2CC Register Offsets ****************************************************/ +#define IMX_ARMMP_PSECTION 0x00a00000 /* 00a00000-00afffff 8 KB ARM MP */ +# define IMX_ARMMP_VSECTION IMX_ARMMP_PSECTION /* 8 KB ARM MP */ +#define IMX_PL310_OFFSET 0x00002000 /* 00002000-00002fff 4 KB PL310 (L2 Cache controller) */ +#define IMX_PL310_VBASE (IMX_ARMMP_VSECTION+IMX_PL310_OFFSET) +#define L2CC_VBASE IMX_PL310_VBASE + + +#define L2CC_IDR_OFFSET 0x0000 /* Cache ID Register */ +#define L2CC_TYPR_OFFSET 0x0004 /* Cache Type Register */ +#define L2CC_CR_OFFSET 0x0100 /* Control Register */ +#define L2CC_ACR_OFFSET 0x0104 /* Auxiliary Control Register */ +#define L2CC_TRCR_OFFSET 0x0108 /* Tag RAM Control Register */ +#define L2CC_DRCR_OFFSET 0x010c /* Data RAM Control Register */ + /* 0x0110-0x01fc Reserved */ +#define L2CC_ECR_OFFSET 0x0200 /* Event Counter Control Register */ +#define L2CC_ECFGR1_OFFSET 0x0204 /* Event Counter 1 Configuration Register */ +#define L2CC_ECFGR0_OFFSET 0x0208 /* Event Counter 0 Configuration Register */ +#define L2CC_EVR1_OFFSET 0x020c /* Event Counter 1 Value Register */ +#define L2CC_EVR0_OFFSET 0x0210 /* Event Counter 0 Value Register */ +#define L2CC_IMR_OFFSET 0x0214 /* Interrupt Mask Register */ +#define L2CC_MISR_OFFSET 0x0218 /* Masked Interrupt Status Register */ +#define L2CC_RISR_OFFSET 0x021c /* Raw Interrupt Status Register */ +#define L2CC_ICR_OFFSET 0x0220 /* Interrupt Clear Register */ + /* 0x0224-0x072c Reserved */ +#define L2CC_CSR_OFFSET 0x0730 /* Cache Synchronization Register */ + /* 0x0734-0x076c Reserved */ +#define L2CC_IPALR_OFFSET 0x0770 /* Invalidate Physical Address Line Register */ + /* 0x0774-0x0778 Reserved */ +#define L2CC_IWR_OFFSET 0x077c /* Invalidate Way Register */ + /* 0x0780-0x07af Reserved */ +#define L2CC_CPALR_OFFSET 0x07b0 /* Clean Physical Address Line Register */ + /* 0x07b4 Reserved */ +#define L2CC_CIR_OFFSET 0x07b8 /* Clean Index Register */ +#define L2CC_CWR_OFFSET 0x07bc /* Clean Way Register */ + /* 0x07c0-0x07ec Reserved */ +#define L2CC_CIPALR_OFFSET 0x07f0 /* Clean Invalidate Physical Address Line Register */ + /* 0x07f4 Reserved */ +#define L2CC_CIIR_OFFSET 0x07f8 /* Clean Invalidate Index Register */ +#define L2CC_CIWR_OFFSET 0x07fc /* Clean Invalidate Way Register */ + /* 0x0800-0x08fc Reserved */ + +/* Data and Instruction Lockdown registers where n=0-7. + * The registers for n > 0 are implemented if the option + * pl310_LOCKDOWN_BY_MASTER is enabled. + * Otherwise, they are unused + */ + +#define L2CC_DLKR_OFFSET(n) (0x0900 + ((n) << 3)) /* Data Lockdown Register */ +#define L2CC_ILKR_OFFSET(n) (0x0904 + ((n) << 3)) /* Instruction Lockdown Register */ + /* 0x0940-0x0f4c Reserved */ +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_OFFSET 0x0950 /* Lock Line Enable Register */ +# define L2CC_UNLKW_OFFSET 0x0954 /* Unlock Way Register */ +#endif + /* 0x0958-0x0bfc Reserved */ +#define L2CC_FLSTRT_OFFSET 0x0c00 /* Address filter start */ +#define L2CC_FLEND_OFFSET 0x0c04 /* Address filter end */ + /* 0x0c08-0x0f3c Reserved */ +#define L2CC_DCR_OFFSET 0x0f40 /* Debug Control Register */ + /* 0x0f44-0x0f5c Reserved */ +#define L2CC_PCR_OFFSET 0x0f60 /* Prefetch Control Register */ + /* 0x0f64-0x0f7c Reserved */ +#define L2CC_POWCR_OFFSET 0x0f80 /* Power Control Register */ + +/* L2CC Register Addresses **************************************************/ + +#define L2CC_IDR (L2CC_VBASE+L2CC_IDR_OFFSET) +#define L2CC_TYPR (L2CC_VBASE+L2CC_TYPR_OFFSET) +#define L2CC_CR (L2CC_VBASE+L2CC_CR_OFFSET) +#define L2CC_ACR (L2CC_VBASE+L2CC_ACR_OFFSET) +#define L2CC_TRCR (L2CC_VBASE+L2CC_TRCR_OFFSET) +#define L2CC_DRCR (L2CC_VBASE+L2CC_DRCR_OFFSET) +#define L2CC_ECR (L2CC_VBASE+L2CC_ECR_OFFSET) +#define L2CC_ECFGR1 (L2CC_VBASE+L2CC_ECFGR1_OFFSET) +#define L2CC_ECFGR0 (L2CC_VBASE+L2CC_ECFGR0_OFFSET) +#define L2CC_EVR1 (L2CC_VBASE+L2CC_EVR1_OFFSET) +#define L2CC_EVR0 (L2CC_VBASE+L2CC_EVR0_OFFSET) +#define L2CC_IMR (L2CC_VBASE+L2CC_IMR_OFFSET) +#define L2CC_MISR (L2CC_VBASE+L2CC_MISR_OFFSET) +#define L2CC_RISR (L2CC_VBASE+L2CC_RISR_OFFSET) +#define L2CC_ICR (L2CC_VBASE+L2CC_ICR_OFFSET) +#define L2CC_CSR (L2CC_VBASE+L2CC_CSR_OFFSET) +#define L2CC_IPALR (L2CC_VBASE+L2CC_IPALR_OFFSET) +#define L2CC_IWR (L2CC_VBASE+L2CC_IWR_OFFSET) +#define L2CC_CPALR (L2CC_VBASE+L2CC_CPALR_OFFSET) +#define L2CC_CIR (L2CC_VBASE+L2CC_CIR_OFFSET) +#define L2CC_CWR (L2CC_VBASE+L2CC_CWR_OFFSET) +#define L2CC_CIPALR (L2CC_VBASE+L2CC_CIPALR_OFFSET) +#define L2CC_CIIR (L2CC_VBASE+L2CC_CIIR_OFFSET) +#define L2CC_CIWR (L2CC_VBASE+L2CC_CIWR_OFFSET) +#define L2CC_DLKR(n) (L2CC_VBASE+L2CC_DLKR_OFFSET(n)) +#define L2CC_ILKR(n) (L2CC_VBASE+L2CC_ILKR_OFFSET(n)) + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN (L2CC_VBASE+L2CC_LKLN_OFFSET) +# define L2CC_UNLKW (L2CC_VBASE+L2CC_UNLKW_OFFSET) +#endif + +#define L2CC_FLSTRT (L2CC_VBASE+L2CC_FLSTRT_OFFSET) +#define L2CC_FLEND (L2CC_VBASE+L2CC_FLEND_OFFSET) +#define L2CC_DCR (L2CC_VBASE+L2CC_DCR_OFFSET) +#define L2CC_PCR (L2CC_VBASE+L2CC_PCR_OFFSET) +#define L2CC_POWCR (L2CC_VBASE+L2CC_POWCR_OFFSET) + +/* L2CC Register Bit Definitions ********************************************/ + +/* Cache ID Register (32-bit ID) */ + +#define L2CC_IDR_REV_MASK 0x0000003f +#define L2CC_IDR_REV_R0P0 0x00000000 +#define L2CC_IDR_REV_R1P0 0x00000002 +#define L2CC_IDR_REV_R2P0 0x00000004 +#define L2CC_IDR_REV_R3P0 0x00000005 +#define L2CC_IDR_REV_R3P1 0x00000006 +#define L2CC_IDR_REV_R3P2 0x00000008 + +/* Cache Type Register */ + +#define L2CC_TYPR_IL2ASS (1 << 6) /* Bit 6: Instruction L2 Cache Associativity */ +#define L2CC_TYPR_IL2WSIZE_SHIFT (8) /* Bits 8-10: Instruction L2 Cache Way Size */ +#define L2CC_TYPR_IL2WSIZE_MASK (7 << L2CC_TYPR_IL2WSIZE_SHIFT) +#define L2CC_TYPR_IL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_IL2WSIZE_SHIFT) +#define L2CC_TYPR_DL2ASS (1 << 18) /* Bit 18: Data L2 Cache Associativity */ +#define L2CC_TYPR_DL2WSIZE_SHIFT (20) /* Bits 20-22: Data L2 Cache Way Size */ +#define L2CC_TYPR_DL2WSIZE_MASK (7 << L2CC_TYPR_DL2WSIZE_SHIFT) +#define L2CC_TYPR_DL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_DL2WSIZE_SHIFT) + +/* Control Register */ + +#define L2CC_CR_L2CEN (1 << 0) /* Bit 0: L2 Cache Enable */ + +/* Auxiliary Control Register */ + +#define L2CC_ACR_FLZE (1 << 0) /* Bit 0: Full line zero enable */ +#define L2CC_ACR_HPSO (1 << 10) /* Bit 10: High Priority for SO and Dev Reads Enable */ +#define L2CC_ACR_SBDLE (1 << 11) /* Bit 11: Store Buffer Device Limitation Enable */ +#define L2CC_ACR_EXCC (1 << 12) /* Bit 12: Exclusive Cache Configuration */ +#define L2CC_ACR_SAIE (1 << 13) /* Bit 13: Shared Attribute Invalidate Enable */ +#define L2CC_ACR_ASS (1 << 16) /* Bit 16: Associativity */ +#define L2CC_ACR_WAYSIZE_SHIFT (17) /* Bits 17-19: Way Size */ +#define L2CC_ACR_WAYSIZE_MASK (7 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_16KB (1 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_32KB (2 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_64KB (3 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_128KB (4 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_256KB (5 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_WAYSIZE_512KB (6 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_EMBEN (1 << 20) /* Bit 20: Event Monitor Bus Enable */ +#define L2CC_ACR_PEN (1 << 21) /* Bit 21: Parity Enable */ +#define L2CC_ACR_SAOEN (1 << 22) /* Bit 22: Shared Attribute Override Enable */ +#define L2CC_ACR_FWA_SHIFT (23) /* Bits 23-24: Force Write Allocate */ +#define L2CC_ACR_FWA_MASK (3 << L2CC_ACR_FWA_SHIFT) +#define L2CC_ACR_FWA_AWCACHE (0 << L2CC_ACR_FWA_SHIFT) /* Use AWCACHE attributes for WA */ +#define L2CC_ACR_FWA_NOALLOC (1 << L2CC_ACR_FWA_SHIFT) /* No allocate */ +#define L2CC_ACR_FWA_OVERRIDE (2 << L2CC_ACR_FWA_SHIFT) /* Override AWCACHE attributes */ +#define L2CC_ACR_FWA_MAPPED (3 << L2CC_ACR_FWA_SHIFT) /* Internally mapped to 00 */ + +#define L2CC_ACR_CRPOL (1 << 25) /* Bit 25: Cache Replacement Policy */ +#define L2CC_ACR_NSLEN (1 << 26) /* Bit 26: Non-Secure Lockdown Enable */ +#define L2CC_ACR_NSIAC (1 << 27) /* Bit 27: Non-Secure Interrupt Access Control */ +#define L2CC_ACR_DPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_ACR_IPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_ACR_EBRESP (1 << 30) /* Bit 30: Early BRESP enable */ + +#define L2CC_ACR_SBZ (0x8000c1fe) + +/* Tag RAM Control Register */ + +#define L2CC_TRCR_TSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_TRCR_TSETLAT_MASK (7 << L2CC_TRCR_TSETLAT_SHIFT) +#define L2CC_TRCR_TSETLAT(n) ((uint32_t)(n) << L2CC_TRCR_TSETLAT_SHIFT) +#define L2CC_TRCR_TRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_TRCR_TRDLAT_MASK (7 << L2CC_TRCR_TRDLAT_SHIFT) +#define L2CC_TRCR_TRDLAT(n) ((uint32_t)(n) << L2CC_TRCR_TRDLAT_SHIFT) +#define L2CC_TRCR_TWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_TRCR_TWRLAT_MASK (7 << L2CC_TRCR_TWRLAT_SHIFT) +#define L2CC_TRCR_TWRLAT(n) ((uint32_t)(n) << L2CC_TRCR_TWRLAT_SHIFT) + +/* Data RAM Control Register */ + +#define L2CC_DRCR_DSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_DRCR_DSETLAT_MASK (7 << L2CC_DRCR_DSETLAT_SHIFT) +#define L2CC_DRCR_DSETLAT(n) ((uint32_t)(n) << L2CC_DRCR_DSETLAT_SHIFT) +#define L2CC_DRCR_DRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_DRCR_DRDLAT_MASK (7 << L2CC_DRCR_DRDLAT_SHIFT) +#define L2CC_DRCR_DRDLAT(n) ((uint32_t)(n) << L2CC_DRCR_DRDLAT_SHIFT) +#define L2CC_DRCR_DWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_DRCR_DWRLAT_MASK (7 << L2CC_DRCR_DWRLAT_SHIFT) +#define L2CC_DRCR_DWRLAT(n) ((uint32_t)(n) << L2CC_DRCR_DWRLAT_SHIFT) + +/* Event Counter Control Register */ + +#define L2CC_ECR_EVCEN (1 << 0) /* Bit 0: Event Counter Enable */ +#define L2CC_ECR_EVC0RST (1 << 1) /* Bit 1: Event Counter 0 Reset */ +#define L2CC_ECR_EVC1RST (1 << 2) /* Bit 2: Event Counter 1 Reset */ + +/* Event Counter 1 Configuration Register */ + +#define L2CC_ECFGR1_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR1_EIGEN_MASK (3 << L2CC_ECFGR1_EIGEN_SHIFT) +#define L2CC_ECFGR1_EIGEN_INTDIS (0 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables (default) */ +#define L2CC_ECFGR1_EIGEN_INTENINCR (1 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Increment condition */ +#define L2CC_ECFGR1_EIGEN_INTENOVER (2 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Overflow condition */ +#define L2CC_ECFGR1_EIGEN_INTGENDIS (3 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR1_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR1_ESRC_MASK (15 << L2CC_ECFGR1_ESRC_SHIFT) +#define L2CC_ECFGR1_ESRC_CNTDIS (0 << L2CC_ECFGR1_ESRC_SHIFT) /* Counter Disabled */ +#define L2CC_ECFGR1_ESRC_CO (1 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is CO */ +#define L2CC_ECFGR1_ESRC_DRHIT (2 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRHIT */ +#define L2CC_ECFGR1_ESRC_DRREQ (3 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRREQ */ +#define L2CC_ECFGR1_ESRC_DWHIT (4 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWHIT */ +#define L2CC_ECFGR1_ESRC_DWREQ (5 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWREQ */ +#define L2CC_ECFGR1_ESRC_DWTREQ (6 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWTREQ */ +#define L2CC_ECFGR1_ESRC_IRHIT (7 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRHIT */ +#define L2CC_ECFGR1_ESRC_IRREQ (8 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRREQ */ +#define L2CC_ECFGR1_ESRC_WA (9 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is WA */ +#define L2CC_ECFGR1_ESRC_IPFALLOC (10 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IPFALLOC */ +#define L2CC_ECFGR1_ESRC_EPFHIT (11 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFHIT */ +#define L2CC_ECFGR1_ESRC_EPFALLOC (12 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFALLOC */ +#define L2CC_ECFGR1_ESRC_SRRCVD (13 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRRCVD */ +#define L2CC_ECFGR1_ESRC_SRCONF (14 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRCONF */ +#define L2CC_ECFGR1_ESRC_EPFRCVD (15 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 0 Configuration Register */ + +#define L2CC_ECFGR0_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR0_EIGEN_MASK (3 << L2CC_ECFGR0_EIGEN_SHIFT) +#define L2CC_ECFGR0_EIGEN_INTDIS (0 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables (default) */ +#define L2CC_ECFGR0_EIGEN_INTENINCR (1 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Increment condition */ +#define L2CC_ECFGR0_EIGEN_INTENOVER (2 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Overflow condition */ +#define L2CC_ECFGR0_EIGEN_INTGENDIS (3 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR0_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR0_ESRC_MASK (15 << L2CC_ECFGR0_ESRC_SHIFT) +#define L2CC_ECFGR0_ESRC_CNTDIS (0 << L2CC_ECFGR0_ESRC_SHIFT) /* Counter Disabled */ +#define L2CC_ECFGR0_ESRC_CO (1 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is CO */ +#define L2CC_ECFGR0_ESRC_DRHIT (2 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRHIT */ +#define L2CC_ECFGR0_ESRC_DRREQ (3 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRREQ */ +#define L2CC_ECFGR0_ESRC_DWHIT (4 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWHIT */ +#define L2CC_ECFGR0_ESRC_DWREQ (5 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWREQ */ +#define L2CC_ECFGR0_ESRC_DWTREQ (6 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWTREQ */ +#define L2CC_ECFGR0_ESRC_IRHIT (7 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRHIT */ +#define L2CC_ECFGR0_ESRC_IRREQ (8 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRREQ */ +#define L2CC_ECFGR0_ESRC_WA (9 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is WA */ +#define L2CC_ECFGR0_ESRC_IPFALLOC (10 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IPFALLOC */ +#define L2CC_ECFGR0_ESRC_EPFHIT (11 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFHIT */ +#define L2CC_ECFGR0_ESRC_EPFALLOC (12 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFALLOC */ +#define L2CC_ECFGR0_ESRC_SRRCVD (13 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRRCVD */ +#define L2CC_ECFGR0_ESRC_SRCONF (14 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRCONF */ +#define L2CC_ECFGR0_ESRC_EPFRCVD (15 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 1 Value Register (32-bit value) */ + +/* Event Counter 0 Value Register (32-bit value) */ + +/* Interrupt Mask Register, Masked Interrupt Status Register, + * Raw Interrupt Status Register, and Interrupt Clear Register. + */ + +#define L2CC_INT_ECNTR (1 << 0) /* Bit 0: Event Counter 1/0 Overflow Increment */ +#define L2CC_INT_PARRT (1 << 1) /* Bit 1: Parity Error on L2 Tag RAM, Read */ +#define L2CC_INT_PARRD (1 << 2) /* Bit 2: Parity Error on L2 Data RAM, Read */ +#define L2CC_INT_ERRWT (1 << 3) /* Bit 3: Error on L2 Tag RAM, Write */ +#define L2CC_INT_ERRWD (1 << 4) /* Bit 4: Error on L2 Data RAM, Write */ +#define L2CC_INT_ERRRT (1 << 5) /* Bit 5: Error on L2 Tag RAM, Read */ +#define L2CC_INT_ERRRD (1 << 6) /* Bit 6: Error on L2 Data RAM, Read */ +#define L2CC_INT_SLVERR (1 << 7) /* Bit 7: SLVERR from L3 Memory */ +#define L2CC_INT_DECERR (1 << 8) /* Bit 8: DECERR from L3 Memory */ + +/* Cache Synchronization Register */ + +#define L2CC_CSR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ + +/* Invalidate Physical Address Line Register */ + +#define L2CC_IPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_IPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_IPALR_IDX_MASK (0x1ff << L2CC_IPALR_IDX_SHIFT) +#define L2CC_IPALR_IDX(n) ((uint32_t)(n) << L2CC_IPALR_IDX_SHIFT) +#define L2CC_IPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_IPALR_TAG_MASK (0x3ffff << L2CC_IPALR_TAG_SHIFT) +#define L2CC_IPALR_TAG(n) ((uint32_t)(n) << L2CC_IPALR_TAG_SHIFT) + +/* Invalidate Way Register */ + +#define L2CC_IWR_WAY(n) (1 << (n)) /* Bist 0-7: Invalidate Way Number n, n=0..7 */ +#define L2CC_IWR_WAY0 (1 << 0) /* Bit 0: Invalidate Way Number 0 */ +#define L2CC_IWR_WAY1 (1 << 1) /* Bit 1: Invalidate Way Number 1 */ +#define L2CC_IWR_WAY2 (1 << 2) /* Bit 2: Invalidate Way Number 2 */ +#define L2CC_IWR_WAY3 (1 << 3) /* Bit 3: Invalidate Way Number 3 */ +#define L2CC_IWR_WAY4 (1 << 4) /* Bit 4: Invalidate Way Number 4 */ +#define L2CC_IWR_WAY5 (1 << 5) /* Bit 5: Invalidate Way Number 5 */ +#define L2CC_IWR_WAY6 (1 << 6) /* Bit 6: Invalidate Way Number 6 */ +#define L2CC_IWR_WAY7 (1 << 7) /* Bit 7: Invalidate Way Number 7 */ + +/* Clean Physical Address Line Register */ + +#define L2CC_CPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CPALR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CPALR_IDX_MASK (0x1ff << L2CC_CPALR_IDX_SHIFT) +#define L2CC_CPALR_IDX(n) ((uint32_t)(n) << L2CC_CPALR_IDX_SHIFT) +#define L2CC_CPALR_TAG_SHIFT (14) /* Bits 14-31: Tag number */ +#define L2CC_CPALR_TAG_MASK (0x3ffff << L2CC_CPALR_TAG_SHIFT) +#define L2CC_CPALR_TAG(n) ((uint32_t)(n) << L2CC_CPALR_TAG_SHIFT) + +/* Clean Index Register */ + +#define L2CC_CIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CIR_IDX_MASK (0x1ff << L2CC_CIR_IDX_SHIFT) +#define L2CC_CIR_IDX(n) ((uint32_t)(n) << L2CC_CIR_IDX_SHIFT) +#define L2CC_CIR_WAY_SHIFT (28) /* Bits 28-30: Way number */ +#define L2CC_CIR_WAY_MASK (7 << L2CC_CIR_WAY_SHIFT) +#define L2CC_CIR_WAY(n) ((uint32_t)(n) << L2CC_CIR_WAY_SHIFT) + +/* Clean Way Register */ + +#define L2CC_CWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Way Number n, n=0..7 */ +#define L2CC_CWR_WAY0 (1 << 0) /* Bit 0: Clean Way Number 0 */ +#define L2CC_CWR_WAY1 (1 << 1) /* Bit 1: Clean Way Number 1 */ +#define L2CC_CWR_WAY2 (1 << 2) /* Bit 2: Clean Way Number 2 */ +#define L2CC_CWR_WAY3 (1 << 3) /* Bit 3: Clean Way Number 3 */ +#define L2CC_CWR_WAY4 (1 << 4) /* Bit 4: Clean Way Number 4 */ +#define L2CC_CWR_WAY5 (1 << 5) /* Bit 5: Clean Way Number 5 */ +#define L2CC_CWR_WAY6 (1 << 6) /* Bit 6: Clean Way Number 6 */ +#define L2CC_CWR_WAY7 (1 << 7) /* Bit 7: Clean Way Number 7 */ + +/* Clean Invalidate Physical Address Line Register */ + +#define L2CC_CIPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIPALR_IDX_MASK (0x1ff << L2CC_CIPALR_IDX_SHIFT) +#define L2CC_CIPALR_IDX(n) ((uint32_t)(n) << L2CC_CIPALR_IDX_SHIFT) +#define L2CC_CIPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_CIPALR_TAG_MASK (0x3ffff << L2CC_CIPALR_TAG_SHIFT) +#define L2CC_CIPALR_TAG(n) ((uint32_t)(n) << L2CC_CIPALR_TAG_SHIFT) + +/* Clean Invalidate Index Register */ + +#define L2CC_CIIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIIR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIIR_IDX_MASK (0x1ff << L2CC_CIIR_IDX_SHIFT) +#define L2CC_CIIR_IDX(n) ((uint32_t)(n) << L2CC_CIIR_IDX_SHIFT) +#define L2CC_CIIR_WAY_SHIFT (28) /* Bits 28-30: Way Number */ +#define L2CC_CIIR_WAY_MASK (7 << L2CC_CIIR_WAY_SHIFT) +#define L2CC_CIIR_WAY(n) ((uint32_t)(n) << L2CC_CIIR_WAY_SHIFT) + +/* Clean Invalidate Way Register */ + +#define L2CC_CIWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Invalidate Way Number n, n=1..7 */ +#define L2CC_CIWR_WAY0 (1 << 0) /* Bit 0: Clean Invalidate Way Number 0 */ +#define L2CC_CIWR_WAY1 (1 << 1) /* Bit 1: Clean Invalidate Way Number 1 */ +#define L2CC_CIWR_WAY2 (1 << 2) /* Bit 2: Clean Invalidate Way Number 2 */ +#define L2CC_CIWR_WAY3 (1 << 3) /* Bit 3: Clean Invalidate Way Number 3 */ +#define L2CC_CIWR_WAY4 (1 << 4) /* Bit 4: Clean Invalidate Way Number 4 */ +#define L2CC_CIWR_WAY5 (1 << 5) /* Bit 5: Clean Invalidate Way Number 5 */ +#define L2CC_CIWR_WAY6 (1 << 6) /* Bit 6: Clean Invalidate Way Number 6 */ +#define L2CC_CIWR_WAY7 (1 << 7) /* Bit 7: Clean Invalidate Way Number 7 */ + +/* Data Lockdown Register */ + +#define L2CC_DLKR_DLK(n) (1 << (n)) /* Bits 0-7: Data Lockdown in Way Number n, n=0..7 */ +#define L2CC_DLKR_DLK0 (1 << 0) /* Bit 0: Data Lockdown in Way Number 0 */ +#define L2CC_DLKR_DLK1 (1 << 1) /* Bit 1: Data Lockdown in Way Number 1 */ +#define L2CC_DLKR_DLK2 (1 << 2) /* Bit 2: Data Lockdown in Way Number 2 */ +#define L2CC_DLKR_DLK3 (1 << 3) /* Bit 3: Data Lockdown in Way Number 3 */ +#define L2CC_DLKR_DLK4 (1 << 4) /* Bit 4: Data Lockdown in Way Number 4 */ +#define L2CC_DLKR_DLK5 (1 << 5) /* Bit 5: Data Lockdown in Way Number 5 */ +#define L2CC_DLKR_DLK6 (1 << 6) /* Bit 6: Data Lockdown in Way Number 6 */ +#define L2CC_DLKR_DLK7 (1 << 7) /* Bit 7: Data Lockdown in Way Number 7 */ + +/* Instruction Lockdown Register */ + +#define L2CC_ILKR_ILK(n) (1 << (n)) /* Bits 0-7: Instruction Lockdown in Way Number n, n=0..7 */ +#define L2CC_ILKR_ILK0 (1 << 0) /* Bit 0: Instruction Lockdown in Way Number 0 */ +#define L2CC_ILKR_ILK1 (1 << 1) /* Bit 1: Instruction Lockdown in Way Number 1 */ +#define L2CC_ILKR_ILK2 (1 << 2) /* Bit 2: Instruction Lockdown in Way Number 2 */ +#define L2CC_ILKR_ILK3 (1 << 3) /* Bit 3: Instruction Lockdown in Way Number 3 */ +#define L2CC_ILKR_ILK4 (1 << 4) /* Bit 4: Instruction Lockdown in Way Number 4 */ +#define L2CC_ILKR_ILK5 (1 << 5) /* Bit 5: Instruction Lockdown in Way Number 5 */ +#define L2CC_ILKR_ILK6 (1 << 6) /* Bit 6: Instruction Lockdown in Way Number 6 */ +#define L2CC_ILKR_ILK7 (1 << 7) /* Bit 7: Instruction Lockdown in Way Number 7 */ + +/* Lock Line Enable Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_ENABLE (1 << 0) /* Bit 0: Lockdown by line enable */ +#endif + +/* Unlock Way Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_UNLKW_WAY_SHIFT (0) /* Bits 0-15: Unlock line for corresponding way */ +# define L2CC_UNLKW_WAY_MASK (0xffff << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_SET(n) ((uint32_t)(n) << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_BIT(n) ((1 << (n)) << L2CC_UNLKW_WAY_SHIFT) +#endif + +/* Address filter start */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLSTRT_ENABLE (1 << 0) /* Bit 0: Address filter enable */ +# define L2CC_FLSTRT_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Address filter end */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLEND_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Debug Control Register */ + +#define L2CC_DCR_DCL (1 << 0) /* Bit 0: Disable Cache Linefill */ +#define L2CC_DCR_DWB (1 << 1) /* Bit 1: Disable Write-back, Force Write-through */ +#define L2CC_DCR_SPNIDEN (1 << 2) /* Bit 2: SPNIDEN Value */ + +/* Prefetch Control Register */ + +#define L2CC_PCR_SHIFT (0) /* Bits 0-4: Prefetch Offset */ +#define L2CC_PCR_MASK (31 << L2CC_PCR_SHIFT) +#define L2CC_PCR_PREFETCH(n) ((uint32_t)(n) << L2CC_PCR_SHIFT) +#define L2CC_PCR_NSIDEN (1 << 21) /* Bit 21: Not Same ID on Exclusive Sequence Enable */ +#define L2CC_PCR_IDLEN (1 << 23) /* Bit 23: INCR Double Linefill Enable */ +#define L2CC_PCR_PDEN (1 << 24) /* Bit 24: Prefetch Drop Enable */ +#define L2CC_PCR_DLFWRDIS (1 << 27) /* Bit 27: Double Linefill on WRAP Read Disable */ +#define L2CC_PCR_DATPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_PCR_INSPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_PCR_DLEN (1 << 30) /* Bit 30: Double Linefill Enable */ + +/* Power Control Register */ + +#define L2CC_POWCR_STBYEN (1 << 0) /* Bit 0: Standby Mode Enable */ +#define L2CC_POWCR_DCKGATEN (1 << 1) /* Bit 1: Dynamic Clock Gating Enable */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/device.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/device.h new file mode 100644 index 000000000..0b3bde014 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/device.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file l2cc_pl310.c + * @brief PLC inovance am401 app + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2023.8.10 + */ + +#include + +struct uart_desc { + uint32_t RXD_ADDR; + uint32_t TXD_ADDR; +}; + +struct arch_desc { + struct gic_desc { + uint32_t GICC_ADDR; + uint32_t GICD_ADDR; + + } gic; + +}; + + +struct page_pool { + uint32_t node; + uint32_t base; + uint32_t size; + uint32_t free; + uint32_t last; + +}; + +struct mem_region { + uint32_t base; + uint32_t size; + struct page_pool page_pool; +}; + + + + + + +struct board_desc{ + + uint32_t cpu_num; + uint32_t region_num; + struct mem_region *regions; + + struct { + uint32_t base_addr; + } console; + + uint32_t uart_num; + struct uart_desc *uarts; + + struct arch_desc arch; +}; \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/imx6q_desc.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/imx6q_desc.c new file mode 100644 index 000000000..b413d364e --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/imx6q_desc.c @@ -0,0 +1,56 @@ +#include "device.h" + + +struct board_desc platform = { + .cpu_num = 4, + .region_num = 1, + .regions = (struct mem_region[]) { + { + + .base = 0x10000000, + .size = 0xFFFFFFFF - 0x10000000 + } + }, + + +#define URXD 0x0 /* Receiver Register */ +#define UTXD 0x40 /* Transmitter Register */ + + + + +#define AIPS1_ARB_BASE_ADDR 0x02000000 +#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR +#define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) + + +#define AIPS2_ARB_BASE_ADDR 0x02100000 +#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR +#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000) + + .console = { + .base_addr=AIPS2_OFF_BASE_ADDR + 0x68000, + }, + + .arch = { + .gic = { + .GICD_ADDR = 0x00A01000, + .GICC_ADDR = 0x00A00100, + + }, + }, + + .uart_num=2, + .uarts=(struct uart_desc[]){ + //UART 0 + { + .RXD_ADDR=0xF9010000, + .TXD_ADDR=0xF9010000, + }, + //UART 1 + { + .RXD_ADDR=0xF9010000, + .TXD_ADDR=0xF9010000, + } + } +};