diff --git a/arch/tricore/include/arch.h b/arch/tricore/include/arch.h index 8d022db95656b..811d843e7bca8 100644 --- a/arch/tricore/include/arch.h +++ b/arch/tricore/include/arch.h @@ -42,6 +42,20 @@ * Pre-processor Definitions ****************************************************************************/ +/* MTCR and MFCR - move to / from Core Special Function Register */ + +#define tricore_mtcr(reg, val) \ + ({ \ + __asm__ volatile ("mtcr %0,%1\n\t"::"i"(reg),"d"(val):"memory"); \ + }) + +#define tricore_mfcr(reg) \ + ({ \ + uint32_t __val; \ + __asm__ volatile ("mfcr %0,%1": "=d" (__val) :"i"(reg): "memory"); \ + __val; \ + }) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/arch/tricore/include/barriers.h b/arch/tricore/include/barriers.h index b50bc7f464aaa..8d5fbfbfa1314 100644 --- a/arch/tricore/include/barriers.h +++ b/arch/tricore/include/barriers.h @@ -21,11 +21,11 @@ #ifndef __ARCH_TRICORE_INCLUDE_BARRIERS_H #define __ARCH_TRICORE_INCLUDE_BARRIERS_H -#define UP_DSB() __dsync() +#define UP_DSB() __asm__ volatile ("dsync" : : : "memory") #define UP_DMB() asm volatile ("" : : : "memory") #define UP_RMB() asm volatile ("" : : : "memory") #define UP_WMB() asm volatile ("" : : : "memory") -#define UP_ISB() __isync() +#define UP_ISB() __asm__ volatile ("isync" : : : "memory") #endif /* __ARCH_TRICORE_INCLUDE_BARRIERS_H */ diff --git a/arch/tricore/src/common/tricore_cache.c b/arch/tricore/src/common/tricore_cache.c index d86924b024b47..ed281525fd49e 100644 --- a/arch/tricore/src/common/tricore_cache.c +++ b/arch/tricore/src/common/tricore_cache.c @@ -24,15 +24,46 @@ #include -#include +#include +#include -#include "tricore_internal.h" -#include "IfxCpu_cfg.h" +#include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#define CPU_DCON0 0x9040 /* Data Memory Configuration 0 */ +#define CPU_DCON1 0x9008 /* Data Memory Configuration 1 */ +#define CPU_DCON2 0x9000 /* Data Memory Configuration 2 */ +#define CPU_PCON0 0x920C /* Program Memory Configuration 0 */ +#define CPU_PCON1 0x9204 /* Program Memory Configuration 1 */ +#define CPU_PCON2 0x9208 /* Program Memory Configuration 2 */ + +/* I/D-cache line size in bits. */ + +#define ICACHE_LINE_SIZE 256 +#define DCACHE_LINE_SIZE 256 + +/* PCON0/DCON0 bit 1: cache enable/disable. */ + +#define PCON0_ENABLE (0 << 1) +#define PCON0_DISABLE (1 << 1) +#define DCON0_ENABLE (0 << 1) +#define DCON0_DISABLE (1 << 1) + +/* PCON1/DCON1 bit 0: invalidate. */ + +#define PCON1_INVALIDATE (1 << 0) +#define DCON1_INVALIDATE (1 << 0) + +/* PCON2/DCON2 bits 15:0: cache size field. */ + +#define ICACHE_SIZE_MASK (0xffff << 0) +#define DCACHE_SIZE_MASK (0xffff << 0) + +/* Cache instructions. */ + #define tc_invalidate_cache_byaddr(addr) \ __asm__ __volatile__("cachea.i [%0]0"::"a"(addr)) #define tc_clear_cache_byaddr(addr) \ @@ -67,7 +98,7 @@ size_t up_get_icache_linesize(void) { - return IFXCPU_PCACHE_LINE_SIZE / 8; + return ICACHE_LINE_SIZE / 8; } /**************************************************************************** @@ -86,10 +117,7 @@ size_t up_get_icache_linesize(void) size_t up_get_icache_size(void) { - Ifx_CPU_PCON2 pcon2; - - pcon2.U = __mfcr(CPU_PCON2); - return pcon2.B.PCACHE_SZE * 1000; + return (tricore_mfcr(CPU_PCON2) & ICACHE_SIZE_MASK) * 1000; } /**************************************************************************** @@ -111,12 +139,9 @@ size_t up_get_icache_size(void) void up_enable_icache(void) { - Ifx_CPU_PCON0 pcon0; - - pcon0.B.PCBYP = 0; - __mtcr(CPU_PCON0, pcon0.U); + tricore_mtcr(CPU_PCON0, PCON0_ENABLE); - __isync(); + UP_ISB(); } /**************************************************************************** @@ -135,13 +160,9 @@ void up_enable_icache(void) void up_disable_icache(void) { - Ifx_CPU_PCON0 pcon0; + tricore_mtcr(CPU_PCON0, PCON0_DISABLE); - pcon0.U = 0; - pcon0.B.PCBYP = 1; - __mtcr(CPU_PCON0, pcon0.U); - - __isync(); + UP_ISB(); } /**************************************************************************** @@ -180,13 +201,9 @@ void up_invalidate_icache(uintptr_t start, uintptr_t end) void up_invalidate_icache_all(void) { - Ifx_CPU_PCON1 pcon1; - - pcon1.U = 0; - pcon1.B.PCINV = 1; - __mtcr(CPU_PCON1, pcon1.U); + tricore_mtcr(CPU_PCON1, PCON1_INVALIDATE); - __isync(); + UP_ISB(); } #endif @@ -207,7 +224,7 @@ void up_invalidate_icache_all(void) size_t up_get_dcache_linesize(void) { - return IFXCPU_DCACHE_LINE_SIZE / 8; + return DCACHE_LINE_SIZE / 8; } /**************************************************************************** @@ -226,10 +243,7 @@ size_t up_get_dcache_linesize(void) size_t up_get_dcache_size(void) { - Ifx_CPU_DCON2 dcon2; - - dcon2.U = __mfcr(CPU_DCON2); - return dcon2.B.DCACHE_SZE * 1000; + return (tricore_mfcr(CPU_DCON2) & DCACHE_SIZE_MASK) * 1000; } /**************************************************************************** @@ -251,24 +265,19 @@ size_t up_get_dcache_size(void) void up_enable_dcache(void) { - Ifx_CPU_DCON0 dcon0; - /* Check if the D-Cache is enabled */ - dcon0.U = __mfcr(CPU_DCON0); - if (dcon0.B.DCBYP == 0) + if ((tricore_mfcr(CPU_DCON0) & DCON0_DISABLE) == 0) { return; } up_invalidate_dcache_all(); - dcon0.U = 0; - dcon0.B.DCBYP = 0; - __mtcr(CPU_DCON0, dcon0.U); + tricore_mtcr(CPU_DCON0, DCON0_ENABLE); - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -287,13 +296,10 @@ void up_enable_dcache(void) void up_disable_dcache(void) { - Ifx_CPU_DCON0 dcon0; + tricore_mtcr(CPU_DCON0, DCON0_DISABLE); - dcon0.B.DCBYP = 1; - __mtcr(CPU_DCON0, dcon0.U); - - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -338,8 +344,8 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) start += line_size; } - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -358,14 +364,10 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end) void up_invalidate_dcache_all(void) { - Ifx_CPU_DCON1 dcon1; - - dcon1.U = 0; - dcon1.B.DCINV = 1; - __mtcr(CPU_DCON1, dcon1.U); + tricore_mtcr(CPU_DCON1, DCON1_INVALIDATE); - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -396,8 +398,8 @@ void up_clean_dcache(uintptr_t start, uintptr_t end) start += line_size; } - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -428,8 +430,8 @@ void up_clean_dcache_all(void) cache_addr += line_size; } - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -460,8 +462,8 @@ void up_flush_dcache(uintptr_t start, uintptr_t end) start += line_size; } - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** @@ -491,8 +493,8 @@ void up_flush_dcache_all(void) cache_addr += line_size; } - __dsync(); - __isync(); + UP_DSB(); + UP_ISB(); } /**************************************************************************** diff --git a/arch/tricore/src/common/tricore_perf.c b/arch/tricore/src/common/tricore_perf.c index 987c9f12023c0..03d7f0e2082a2 100644 --- a/arch/tricore/src/common/tricore_perf.c +++ b/arch/tricore/src/common/tricore_perf.c @@ -28,7 +28,16 @@ #include #include -#include "tricore_internal.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CPU_CCTRL 0xFC00 /* Counter Control */ +#define CPU_CCNT 0xFC04 /* CPU Clock Cycle Count */ + +/* CPU_CCTRL Count Enable bit. */ + +#define CCTRL_COUNT_ENABLE (1 << 1) #ifdef CONFIG_ARCH_PERF_EVENTS @@ -39,6 +48,28 @@ static unsigned long g_cpu_freq = ULONG_MAX; static invdiv_param64_t g_invdiv_param; +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void tricore_reset_ccnt(void) +{ + uint32_t cctrl = tricore_mfcr(CPU_CCTRL); + + /* Disable and clear the CPU cycle counter */ + + cctrl &= ~CCTRL_COUNT_ENABLE; + tricore_mtcr(CPU_CCTRL, cctrl); + tricore_mtcr(CPU_CCNT, 0); + UP_ISB(); + + /* Re-enable the CPU cycle counter */ + + cctrl |= CCTRL_COUNT_ENABLE; + tricore_mtcr(CPU_CCTRL, cctrl); + UP_ISB(); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -48,7 +79,8 @@ void up_perf_init(void *arg) g_cpu_freq = (unsigned long)(uintptr_t)arg; invdiv_init_param64(g_cpu_freq, &g_invdiv_param); - IfxCpu_resetAndStartCounters(IfxCpu_CounterMode_normal); + + tricore_reset_ccnt(); } unsigned long up_perf_getfreq(void) @@ -58,7 +90,7 @@ unsigned long up_perf_getfreq(void) clock_t up_perf_gettime(void) { - return (clock_t)IfxCpu_getClockCounter(); + return (clock_t)tricore_mfcr(CPU_CCNT); } void up_perf_convert(clock_t elapsed, struct timespec *ts)