Support XiZi_AIoT

This commit is contained in:
TXuian
2024-01-31 10:30:34 +08:00
parent f6cf46027d
commit 494312183b
351 changed files with 46408 additions and 450091 deletions
+3
View File
@@ -0,0 +1,3 @@
SRC_DIR := cortex-a9
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,3 @@
SRC_FILES := l1_cache.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,317 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file: l1_cache.c
* @brief: the general management of L1 cache
* @version: 3.0
* @author: AIIT XUOS Lab
* @date: 2023/11/6
*
*/
/*************************************************
File name: l1_cache.c
Description: the general management of L1 cache
Others:
History:
1. Date: 2023-04-27
Author: AIIT XUOS Lab
Modification:
1、implement the l1 cache operations
*************************************************/
#include "l1_cache.h"
void InvalidateL1Dcache(uintptr_t start, uintptr_t end)
{
uintptr_t length = end - start;
void* addr = (void*)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 = (void*)((uint32_t)addr + line_size);
} while (addr < end_addr);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
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
DSB();
}
void CleanL1Dcache(uintptr_t start, uintptr_t end)
{
void* addr = (void*)start;
uintptr_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 = (void*)((uint32_t)addr + line_size);
} while (addr < end_addr);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
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
DSB();
}
void FlushL1Dcache(uintptr_t start, uintptr_t end)
{
void* addr = (void*)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 = (void*)((uint32_t)addr + line_size);
} while (addr < end_addr);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
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
DSB();
}
void InvalidateL1IcacheAll()
{
uint32_t SBZ = 0x0u;
_ARM_MCR(15, 0, SBZ, 7, 5, 0);
// synchronize context on this processor
ISB();
}
void InvalidateL1Icache(uintptr_t start, uintptr_t end)
{
void* addr = (void*)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 = (void*)((uint32_t)addr + line_size);
} while (addr < end_addr);
// synchronize context on this processor
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
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
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
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
DSB();
}
@@ -0,0 +1,80 @@
/*
* 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: 3.0
* @author: AIIT XUOS Lab
* @date: 2023/4/27
*
*/
/*************************************************
File name: l1_cache.h
Description: the general management of L1 cache
Others:
History:
1. Date: 2023-04-27
Author: AIIT XUOS Lab
Modification:
1、define the l1 cache operations
*************************************************/
#include "core.h"
#include <stdint.h>
/*
* L1 Cache Registers:
*
* Register: DCIMVAC - Invalidate data cache line by VA to PoC.
*
* Register: DCISW - Invalidate data cache line by Set/Way.
*
* Register: DCCMVAC - Clean data cache line to PoC by VA.
*
* Register: DCCSW - Clean data cache line by Set/Way.
*
* Register: DCCMVAU - Clean data or unified cache line by VA to PoU.
*
* Register: DCCIMVAC - Clean and invalidate data cache line by VA to PoC.
*
* Register: DCCISW - Clean and invalidate data cache line by Set/Way.
*/
#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();