Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions arch/tricore/include/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************************************************************************/
Expand Down
4 changes: 2 additions & 2 deletions arch/tricore/include/barriers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

126 changes: 64 additions & 62 deletions arch/tricore/src/common/tricore_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,46 @@

#include <nuttx/config.h>

#include <stdint.h>
#include <arch/arch.h>
#include <arch/barriers.h>

#include "tricore_internal.h"
#include "IfxCpu_cfg.h"
#include <nuttx/cache.h>

/****************************************************************************
* 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) \
Expand Down Expand Up @@ -67,7 +98,7 @@

size_t up_get_icache_linesize(void)
{
return IFXCPU_PCACHE_LINE_SIZE / 8;
return ICACHE_LINE_SIZE / 8;
}

/****************************************************************************
Expand All @@ -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;
}

/****************************************************************************
Expand All @@ -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();
}

/****************************************************************************
Expand All @@ -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();
}

/****************************************************************************
Expand Down Expand Up @@ -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

Expand All @@ -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;
}

/****************************************************************************
Expand All @@ -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;
}

/****************************************************************************
Expand All @@ -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();
}

/****************************************************************************
Expand All @@ -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();
}

/****************************************************************************
Expand Down Expand Up @@ -338,8 +344,8 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
start += line_size;
}

__dsync();
__isync();
UP_DSB();
UP_ISB();
}

/****************************************************************************
Expand All @@ -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();
}

/****************************************************************************
Expand Down Expand Up @@ -396,8 +398,8 @@ void up_clean_dcache(uintptr_t start, uintptr_t end)
start += line_size;
}

__dsync();
__isync();
UP_DSB();
UP_ISB();
}

/****************************************************************************
Expand Down Expand Up @@ -428,8 +430,8 @@ void up_clean_dcache_all(void)
cache_addr += line_size;
}

__dsync();
__isync();
UP_DSB();
UP_ISB();
}

/****************************************************************************
Expand Down Expand Up @@ -460,8 +462,8 @@ void up_flush_dcache(uintptr_t start, uintptr_t end)
start += line_size;
}

__dsync();
__isync();
UP_DSB();
UP_ISB();
}

/****************************************************************************
Expand Down Expand Up @@ -491,8 +493,8 @@ void up_flush_dcache_all(void)
cache_addr += line_size;
}

__dsync();
__isync();
UP_DSB();
UP_ISB();
}

/****************************************************************************
Expand Down
38 changes: 35 additions & 3 deletions arch/tricore/src/common/tricore_perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@
#include <nuttx/clock.h>
#include <nuttx/lib/math32.h>

#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

Expand All @@ -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
****************************************************************************/
Expand All @@ -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)
Expand All @@ -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)
Expand Down
Loading