From c2e21257d0aaf9d7ad9afdd2033341b4392e236f Mon Sep 17 00:00:00 2001 From: lr <1234@qq.com> Date: Mon, 17 Jun 2024 21:06:56 +0800 Subject: [PATCH] kernel normal boot at 3568 --- .../cache/L1/arm/cortex-a55/Makefile | 2 +- .../cache/L1/arm/cortex-a55/cache.S | 336 ++++++++++++++++++ .../cache/L1/arm/cortex-a55/l1_cache.c | 48 +-- .../hardkernel/cache/cache_common_ope.c | 4 +- .../XiZi_AIoT/services/app/simple_server.c | 4 +- 5 files changed, 369 insertions(+), 25 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/cache.S diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/Makefile index 23bc22506..11407977e 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := l1_cache.c +SRC_FILES := l1_cache.c cache.S include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/cache.S b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/cache.S new file mode 100644 index 000000000..95596c6ce --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/cache.S @@ -0,0 +1,336 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * This file is based on sample code from ARMv8 ARM. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#define ASM_NL ; + +#define SYMBOL_NAME(X) X + +// #define SYMBOL_NAME_LABEL(X) X##: + +#define SYMBOL_NAME_LABEL(X) X: + +#ifndef __ALIGN +#define __ALIGN .align 4 +#endif + +#ifndef __ALIGN_STR +#define __ALIGN_STR ".align 4" +#endif + +#define ALIGN __ALIGN +#define ALIGN_STR __ALIGN_STR + +#define LENTRY(name) \ + ALIGN ASM_NL \ + SYMBOL_NAME_LABEL(name) + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name) ASM_NL \ + LENTRY(name) + +#define WEAK(name) \ + .weak SYMBOL_NAME(name) ASM_NL \ + LENTRY(name) + + +#define END(name) \ + .size name, .-name + +#define ENDPROC(name) \ + .type name STT_FUNC ASM_NL \ + END(name) + +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_SA (1 << 3) /* Stack Alignment Check Enable */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_WXN (1 << 19) /* Write Permision Imply XN */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ + +.macro switch_el, xreg, el3_label, el2_label, el1_label + mrs \xreg, CurrentEL + cmp \xreg, 0xc + b.eq \el3_label + cmp \xreg, 0x8 + b.eq \el2_label + cmp \xreg, 0x4 + b.eq \el1_label +.endm + + +/* + * void __asm_dcache_level(level) + * flush or invalidate one level cache. + * + * x0: cache level + * x1: 0 clean & invalidate, 1 invalidate only + * x2~x9: clobbered + */ +ENTRY(__asm_dcache_level) + lsl x12, x0, #1 + msr csselr_el1, x12 /* select cache level */ + isb /* sync change of cssidr_el1 */ + mrs x6, ccsidr_el1 /* read the new cssidr_el1 */ + and x2, x6, #7 /* x2 <- log2(cache line size)-4 */ + add x2, x2, #4 /* x2 <- log2(cache line size) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */ + clz w5, w3 /* bit position of #ways */ + mov x4, #0x7fff + and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */ + /* x12 <- cache level << 1 */ + /* x2 <- line length offset */ + /* x3 <- number of cache ways - 1 */ + /* x4 <- number of cache sets - 1 */ + /* x5 <- bit position of #ways */ + +loop_set: + mov x6, x3 /* x6 <- working copy of #ways */ +loop_way: + lsl x7, x6, x5 + orr x9, x12, x7 /* map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + tbz w1, #0, 1f + dc isw, x9 + b 2f +1: dc cisw, x9 /* clean & invalidate by set/way */ +2: subs x6, x6, #1 /* decrement the way */ + b.ge loop_way + subs x4, x4, #1 /* decrement the set */ + b.ge loop_set + + ret +ENDPROC(__asm_dcache_level) + + +/* + * void __asm_flush_dcache_all(int invalidate_only) + * + * x0: 0 clean & invalidate, 1 invalidate only + * + * flush or invalidate all data cache by SET/WAY. + */ + +ENTRY(__asm_dcache_all) + mov x1, x0 + dsb sy + mrs x10, clidr_el1 /* read clidr_el1 */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 <- loc */ + cbz x11, finished /* if loc is 0, exit */ + mov x15, lr + mov x0, #0 /* start flush at cache level 0 */ + /* x0 <- cache level */ + /* x10 <- clidr_el1 */ + /* x11 <- loc */ + /* x15 <- return address */ + +loop_level: + lsl x12, x0, #1 + add x12, x12, x0 /* x0 <- tripled cache level */ + lsr x12, x10, x12 + and x12, x12, #7 /* x12 <- cache type */ + cmp x12, #2 + b.lt skip /* skip if no cache or icache */ + bl __asm_dcache_level /* x1 = 0 flush, 1 invalidate */ +skip: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt loop_level + + mov x0, #0 + msr csselr_el1, x0 /* restore csselr_el1 */ + dsb sy + isb + mov lr, x15 + +finished: + ret +ENDPROC(__asm_dcache_all) + + +ENTRY(__asm_flush_dcache_all) + mov x0, #0 + b __asm_dcache_all +ENDPROC(__asm_flush_dcache_all) + + +ENTRY(__asm_invalidate_dcache_all) + mov x0, #0x1 + b __asm_dcache_all +ENDPROC(__asm_invalidate_dcache_all) + + +/* + * void __asm_flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ + +ENTRY(__asm_flush_dcache_range) + isb + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 /* clean & invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + isb + ret +ENDPROC(__asm_flush_dcache_range) + +/* + * void __asm_invalidate_dcache_range(start, end) + * + * invalidate data cache in the range + * + * x0: start address + * x1: end address + */ + +ENTRY(__asm_invalidate_dcache_range) + mrs x3, ctr_el0 + ubfm x3, x3, #16, #19 + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc ivac, x0 /* invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + isb + ret +ENDPROC(__asm_invalidate_dcache_range) + + +/* + * void __asm_invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ + +ENTRY(__asm_invalidate_icache_all) + ic ialluis + isb sy + ret +ENDPROC(__asm_invalidate_icache_all) + + + +ENTRY(__asm_invalidate_l3_dcache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(__asm_invalidate_l3_dcache) + .weak __asm_invalidate_l3_dcache + + + +ENTRY(__asm_flush_l3_dcache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(__asm_flush_l3_dcache) + .weak __asm_flush_l3_dcache + + + +ENTRY(__asm_invalidate_l3_icache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(__asm_invalidate_l3_icache) + .weak __asm_invalidate_l3_icache + + +/* + * void __asm_switch_ttbr(ulong new_ttbr) + * + * Safely switches to a new page table. + */ + +ENTRY(__asm_switch_ttbr) + /* x2 = SCTLR (alive throghout the function) */ + switch_el x4, 3f, 2f, 1f +3: mrs x2, sctlr_el3 + b 0f +2: mrs x2, sctlr_el2 + b 0f +1: mrs x2, sctlr_el1 +0: + + /* Unset CR_M | CR_C | CR_I from SCTLR to disable all caches */ + movn x1, #(CR_M | CR_C | CR_I) + and x1, x2, x1 + switch_el x4, 3f, 2f, 1f +3: msr sctlr_el3, x1 + b 0f +2: msr sctlr_el2, x1 + b 0f +1: msr sctlr_el1, x1 +0: isb + + /* This call only clobbers x30 (lr) and x9 (unused) */ + mov x3, x30 + bl __asm_invalidate_tlb_all + + /* From here on we're running safely with caches disabled */ + + /* Set TTBR to our first argument */ + switch_el x4, 3f, 2f, 1f +3: msr ttbr0_el3, x0 + b 0f +2: msr ttbr0_el2, x0 + b 0f +1: msr ttbr0_el1, x0 +0: isb + + /* Restore original SCTLR and thus enable caches again */ + switch_el x4, 3f, 2f, 1f +3: msr sctlr_el3, x2 + b 0f +2: msr sctlr_el2, x2 + b 0f +1: msr sctlr_el1, x2 +0: isb + + ret x3 +ENDPROC(__asm_switch_ttbr) + +ENTRY(__asm_invalidate_tlb_all) + switch_el x9, 3f, 2f, 1f +3: tlbi alle3 + dsb sy + isb + b 0f +2: tlbi alle2 + dsb sy + isb + b 0f +1: tlbi vmalle1 + dsb sy + isb +0: + ret +ENDPROC(__asm_invalidate_tlb_all) \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/l1_cache.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/l1_cache.c index eb2dfd2ee..37a157f0f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/l1_cache.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/arm/cortex-a55/l1_cache.c @@ -20,6 +20,10 @@ Modification: *************************************************/ #include "l1_cache.h" +extern void __asm_flush_dcache_all(); +extern void __asm_flush_l3_dcache(); +extern void __asm_invalidate_icache_all(); +extern void __asm_invalidate_l3_icache(); void InvalidateL1Dcache(uintptr_t start, uintptr_t end) { @@ -153,34 +157,38 @@ void FlushL1Dcache(uintptr_t start, uintptr_t end) 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 + // 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 + // __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; + // // 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)); - } - } + // // 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(); + // // All Cache, Branch predictor and TLB maintenance operations before followed instruction complete + // DSB(); + __asm_flush_dcache_all(); + __asm_flush_l3_dcache(); } void InvalidateL1IcacheAll() { - __asm__ __volatile__("ic iallu\n\t"); - // synchronize context on this processor - ISB(); + // __asm__ __volatile__("ic iallu\n\t"); + // // synchronize context on this processor + // ISB(); + __asm_invalidate_icache_all(); + __asm_invalidate_l3_icache(); } void InvalidateL1Icache(uintptr_t start, uintptr_t end) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index 8b19d959f..e2b9e8465 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -92,7 +92,7 @@ static inline void invalidate_icache(uintptr_t start, uintptr_t end) static inline void invalidate_icache_all(void) { - // InvalidateL1IcacheAll(); + InvalidateL1IcacheAll(); } /**************************************************************************** @@ -151,7 +151,7 @@ static inline void flush_dcache(uintptr_t start, uintptr_t end) static inline void flush_dcache_all(void) { - // FlushL1DcacheAll(); + FlushL1DcacheAll(); // FlushL2CacheAll(); } diff --git a/Ubiquitous/XiZi_AIoT/services/app/simple_server.c b/Ubiquitous/XiZi_AIoT/services/app/simple_server.c index e6eafe275..f9ae98ee8 100755 --- a/Ubiquitous/XiZi_AIoT/services/app/simple_server.c +++ b/Ubiquitous/XiZi_AIoT/services/app/simple_server.c @@ -30,8 +30,8 @@ int IPC_DO_SERVE_FUNC(Ipc_hello_string)(char* buf, int* len) return 0; } -// IPC_SERVER_INTERFACE(Ipc_add, 2); -IPC_SERVER_THREAD_INTERFACE(Ipc_add, 2); +IPC_SERVER_INTERFACE(Ipc_add, 2); +//IPC_SERVER_THREAD_INTERFACE(Ipc_add, 2); IPC_SERVER_INTERFACE(Ipc_hello_string, 2); IPC_SERVER_REGISTER_INTERFACES(IpcSimpleServer, 2, Ipc_hello_string, Ipc_add);