TODO: Port ok1028a-c.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
|
||||
SRC_DIR := cortex-a9
|
||||
endif
|
||||
ifneq ($(findstring $(BOARD), ok1028a-c), )
|
||||
SRC_DIR := cortex-a72
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
3
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/Makefile
vendored
Normal file
3
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/Makefile
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := l1_cache.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
285
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/l1_cache.c
vendored
Normal file
285
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/l1_cache.c
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* @file: l1_cache.c
|
||||
* @brief: the general management of L1 cache
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2024/04/23
|
||||
*
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: l1_cache.c
|
||||
Description: the general management of L1 cache
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. implement the l1 cache operations
|
||||
2. function names are modified to apply softkernel developement
|
||||
3. function implementations are from modifications of imx6 SDK package
|
||||
*************************************************/
|
||||
|
||||
#include "l1_cache.h"
|
||||
|
||||
void InvalidateL1Dcache(uintptr_t start, uintptr_t end)
|
||||
{
|
||||
uintptr_t length = end - start;
|
||||
uintptr_t addr = start;
|
||||
uint64_t ccsidr_el1;
|
||||
uint64_t line_size;
|
||||
uint64_t va;
|
||||
// get the cache line size
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : : "=r" (ccsidr_el1));
|
||||
line_size = 1 << ((ccsidr_el1 & 0x7) + 4);
|
||||
|
||||
// align the address with line
|
||||
const void * end_addr = (const void *)((uint64_t)addr + length);
|
||||
|
||||
while (addr < end_addr){
|
||||
va = (uint64_t)addr & (~(line_size - 1));
|
||||
|
||||
//Invalidate data cache line to PoC (Point of Coherence) by va.
|
||||
__asm__ __volatile__("dc ivac, %0 " : : "r" (va));
|
||||
|
||||
// increment addres to next line and decrement lenght
|
||||
addr = (void*)((uint64_t)addr + line_size);
|
||||
}
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
void InvalidateL1DcacheAll(void)
|
||||
{
|
||||
uint64_t ccsidr_el1; // Cache Size ID
|
||||
int num_sets; // number of sets
|
||||
int num_ways; // number of ways
|
||||
uint32_t wayset; // wayset parameter
|
||||
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : : "=r" (ccsidr_el1));// Read Cache Size ID
|
||||
|
||||
// Fill number of sets and number of ways from ccsidr_el1 register
|
||||
num_sets = ((ccsidr_el1 >> 32) & 0x7FFF) + 1;
|
||||
num_ways = ((ccsidr_el1 >> 0) & 0x7FFF) + 1;
|
||||
|
||||
// Invalidation all lines (all Sets in all ways)
|
||||
for (int way = 0 ; way < num_ways; way++){
|
||||
for (int set = 0 ;set < num_sets; set++){
|
||||
wayset = (way << 30) | (set << 5);
|
||||
__asm__ __volatile__("dc isw, %0" : : "r" (wayset));
|
||||
}
|
||||
}
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
|
||||
void CleanL1Dcache(uintptr_t start, uintptr_t end)
|
||||
{
|
||||
void* addr = (void*)start;
|
||||
uintptr_t length = end - start;
|
||||
const void * end_addr = (const void *)((uint64_t)addr + length);
|
||||
uint64_t ccsidr_el1;
|
||||
uint64_t line_size;
|
||||
uint64_t va;
|
||||
|
||||
// get the cache line size
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : "=r" (ccsidr_el1));
|
||||
line_size = 1 << ((ccsidr_el1 & 0x7) + 4);
|
||||
|
||||
do
|
||||
{
|
||||
va = (uint64_t)addr & (~(line_size - 1));
|
||||
// Clean data cache line to PoC (Point of Coherence) by va.
|
||||
__asm__ __volatile__("dc cvac, %0" : : "r" (va));
|
||||
|
||||
// increment addres to next line and decrement lenght
|
||||
addr = (void*)((uint64_t)addr + line_size);
|
||||
} while (addr < end_addr);
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
void CleanL1DcacheAll(void)
|
||||
{
|
||||
uint64_t ccsidr_el1; // Cache Size ID
|
||||
int num_sets; // number of sets
|
||||
int num_ways; // number of ways
|
||||
uint32_t wayset; // wayset parameter
|
||||
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : : "=r" (ccsidr_el1));// Read Cache Size ID
|
||||
|
||||
// Fill number of sets and number of ways from ccsidr_el1 register This walues are decremented by 1
|
||||
num_sets = ((ccsidr_el1 >> 32) & 0x7FFF) + 1;
|
||||
num_ways = ((ccsidr_el1 >> 0) & 0x7FFF) + 1;
|
||||
|
||||
// clean all lines (all Sets in all ways)
|
||||
for (int way = 0 ; way < num_ways; way++){
|
||||
for (int set = 0 ;set < num_sets; set++){
|
||||
wayset = (way << 30) | (set << 5);
|
||||
__asm__ __volatile__("dc csw, %0" : : "r" (wayset));
|
||||
}
|
||||
}
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
void FlushL1Dcache(uintptr_t start, uintptr_t end)
|
||||
{
|
||||
void* addr = (void*)start;
|
||||
// size_t length=end-start;
|
||||
uint64_t va;
|
||||
uint64_t ccsidr_el1 = 0, line_size = 0;
|
||||
const void * end_addr = (const void *)((uint64_t)end);
|
||||
|
||||
// get the cache line size
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : "=r" (ccsidr_el1));
|
||||
line_size = 1 << ((ccsidr_el1 & 0x7) + 4);
|
||||
|
||||
do
|
||||
{
|
||||
// Clean data cache line to PoC (Point of Coherence) by va.
|
||||
va = (uint64_t) ((uint64_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK
|
||||
__asm__ __volatile__("dc civac, %0" : : "r" (va));
|
||||
|
||||
// increment addres to next line and decrement lenght
|
||||
addr = (void*)((uint64_t)addr + line_size);
|
||||
} while (addr < end_addr);
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
void FlushL1DcacheAll(void)
|
||||
{
|
||||
uint64_t ccsidr_el1; // Cache Size ID
|
||||
int num_sets; // number of sets
|
||||
int num_ways; // number of ways
|
||||
uint32_t wayset; // wayset parameter
|
||||
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : : "=r" (ccsidr_el1));// Read Cache Size ID
|
||||
|
||||
// Fill number of sets and number of ways from ccsidr_el1 register This walues are decremented by 1
|
||||
num_sets = ((ccsidr_el1 >> 32) & 0x7FFF) + 1;
|
||||
num_ways = ((ccsidr_el1 >> 0) & 0x7FFF) + 1;
|
||||
|
||||
// clean and invalidate all lines (all Sets in all ways)
|
||||
for (int way = 0 ; way < num_ways; way++){
|
||||
for (int set = 0 ;set < num_sets; set++){
|
||||
wayset = (way << 30) | (set << 5);
|
||||
__asm__ __volatile__("dc cisw, %0" : : "r" (wayset));
|
||||
}
|
||||
}
|
||||
|
||||
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
|
||||
DSB();
|
||||
}
|
||||
|
||||
void InvalidateL1IcacheAll()
|
||||
{
|
||||
__asm__ __volatile__("ic iallu\n\t");
|
||||
// synchronize context on this processor
|
||||
ISB();
|
||||
}
|
||||
|
||||
void InvalidateL1Icache(uintptr_t start, uintptr_t end)
|
||||
{
|
||||
uintptr_t length = end - start;
|
||||
uintptr_t addr = start;
|
||||
uint64_t ccsidr_el1;
|
||||
uint64_t line_size;
|
||||
uint64_t va;
|
||||
// get the cache line size
|
||||
__asm__ __volatile__("mrs %0, ccsidr_el1" : : "=r" (ccsidr_el1));
|
||||
line_size = 1 << ((ccsidr_el1 & 0x7) + 4);
|
||||
|
||||
while (addr < end){
|
||||
va = (uint64_t)addr & (~(line_size - 1));
|
||||
|
||||
//Invalidate data cache line to PoC (Point of Coherence) by va.
|
||||
__asm__ __volatile__("dc ivau, %0 " : : "r" (va));
|
||||
// increment addres to next line and decrement lenght
|
||||
addr = (void*)((uint64_t)addr + line_size);
|
||||
}
|
||||
|
||||
// synchronize context on this processor
|
||||
ISB();
|
||||
}
|
||||
|
||||
|
||||
void EnableL1Dcache()
|
||||
{
|
||||
uint64_t sctlr_el1; // System Control Register
|
||||
|
||||
// read sctlr_el1
|
||||
__asm__ __volatile__("mrs %0, sctlr_el1" : :"=r" (sctlr_el1));
|
||||
|
||||
if (!(sctlr_el1 & SCTLR_EL1_DCACHE_ENABLE))
|
||||
{
|
||||
// set C bit (data caching enable)
|
||||
sctlr_el1 |= SCTLR_EL1_DCACHE_ENABLE;
|
||||
|
||||
// write modified sctlr_el1
|
||||
__asm__ __volatile__("msr sctlr_el1, %0" : : "r" (sctlr_el1));
|
||||
|
||||
//data synchronization barrier
|
||||
DSB();
|
||||
}
|
||||
}
|
||||
|
||||
void DisableL1Dcache()
|
||||
{
|
||||
uint64_t sctlr_el1; // System Control Register
|
||||
|
||||
// read sctlr_el1
|
||||
__asm__ __volatile__("mrs %0, sctlr_el1" : : "=r" (sctlr_el1));
|
||||
|
||||
// set C bit (data caching enable)
|
||||
sctlr_el1 &= ~ SCTLR_EL1_DCACHE_ENABLE;
|
||||
|
||||
// write modified sctlr_el1
|
||||
__asm__ __volatile__("msr sctlr_el1, %0" : : "r" (sctlr_el1));
|
||||
|
||||
//data synchronization barrier
|
||||
DSB();
|
||||
}
|
||||
|
||||
void EnableL1Icache()
|
||||
{
|
||||
uint64_t sctlr_el1; // System Control Register
|
||||
|
||||
// read sctlr_el1
|
||||
__asm__ __volatile__("mrs %0, sctlr_el1" : : "=r" (sctlr_el1));
|
||||
|
||||
if (!(sctlr_el1 & SCTLR_EL1_ICACHE_ENABLE))
|
||||
{
|
||||
// set I bit (data caching enable)
|
||||
sctlr_el1 |= SCTLR_EL1_ICACHE_ENABLE;
|
||||
|
||||
// write modified sctlr_el1
|
||||
__asm__ __volatile__("msr sctlr_el1, %0" : : "r" (sctlr_el1));
|
||||
|
||||
//Instruction synchronization barrier
|
||||
ISB();
|
||||
}
|
||||
}
|
||||
|
||||
void DisableL1Icache()
|
||||
{
|
||||
uint64_t sctlr_el1; // System Control Register
|
||||
|
||||
// read sctlr_el1
|
||||
__asm__ __volatile__("mrs %0, sctlr_el1" : : "=r" (sctlr_el1));
|
||||
|
||||
// set I bit (data caching enable)
|
||||
sctlr_el1 &= ~ SCTLR_EL1_ICACHE_ENABLE;
|
||||
|
||||
// write modified sctlr_el1
|
||||
__asm__ __volatile__("msr sctlr_el1, %0" : : "r" (sctlr_el1));
|
||||
|
||||
//Instruction synchronization barrier
|
||||
ISB();
|
||||
}
|
||||
78
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/l1_cache.h
vendored
Normal file
78
Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a72/l1_cache.h
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: l1_cache.h
|
||||
* @brief: the general management of L1 cache
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2024/4/23
|
||||
*
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: l1_cache.h
|
||||
Description: the general management of L1 cache
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1、define the l1 cache operations
|
||||
*************************************************/
|
||||
#include "cortex-a72/core.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* L1 Cache Operation:
|
||||
*
|
||||
* IVAC -Invalidate by Virtual Address, to Point of Coherency AArch32Equivalent :DCIMVAC
|
||||
*
|
||||
* ISW -Invalidate by Set/Way AArch32Equivalent :DCISW
|
||||
*
|
||||
*CVAC -Clean by Virtual Address to Point of Coherency AArch32Equivalent :DCCMVAC
|
||||
*
|
||||
*CSW -Clean by Set/Way AArch32Equivalent :DCCSW
|
||||
*
|
||||
*CVAU -Clean by Virtual Address to Point of Unification AArch32Equivalent :DCCMVAU
|
||||
*
|
||||
*CIVAC -Clean and invalidate data cache line by VA to PoC. AArch32Equivalent :DCCIMVAC
|
||||
*
|
||||
*ISW -Clean and invalidate data cache line by Set/Way. AArch32Equivalent :DCCISW
|
||||
*/
|
||||
|
||||
#define SCTLR_EL1_ICACHE_ENABLE(1 << 12) //!< Instruction cache enable
|
||||
#define SCTLR_EL1_DCACHE_ENABLE (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();
|
||||
Reference in New Issue
Block a user