Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
29 changes: 29 additions & 0 deletions lib/pbio/include/pbdrv/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2025 The Pybricks Authors

#ifndef _PBDRV_CACHE_H_

#include <stddef.h>

// Gets data ready so that the data that we (the CPU) have written
// can be read by DMA peripherals. This cleans the relevant cache lines
// and flushes the write buffer.
void pbdrv_cache_prepare_before_dma(const void *buf, size_t sz);

// Makes sure that we (the CPU) are able to read data written
// by DMA peripherals. This invalidates the relevant cache lines.
void pbdrv_cache_prepare_after_dma(const void *buf, size_t sz);

// Accesses a variable via the uncached memory alias
#define PBDRV_UNCACHED(x) (*(volatile __typeof__(x) *)((uint32_t)(&(x)) + 0x10000000))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems very specific to EV3, so we should rename things accordingly. Or just put this in the tiam1808 library.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely not in tiam1808, since it's specific to the way we've specifically programmed the MMU. PBDRV_EV3_UNCACHED?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah OK. Then I would expect a macro for the 0x10000000 value then that is shared between this and where we program the MMU.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also wondering about the uint32_t. Would it make more sense to use uintptr_t?


// Gets the address of the uncached memory alias of a variable
#define PBDRV_UNCACHED_ADDR(x) ((__typeof__(x) *)((uint32_t)(&(x)) + 0x10000000))

// Cache line size
#define PBDRV_CACHE_LINE_SZ 32

// Align data to a cache line, which is needed for clean RX DMA
#define PBDRV_CACHE_LINE_ALIGNED __attribute__((aligned(PBDRV_CACHE_LINE_SZ)))

#endif
17 changes: 17 additions & 0 deletions lib/pbio/platform/ev3/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

#include <umm_malloc.h>

#include <pbdrv/cache.h>
#include <pbdrv/compiler.h>
#include <pbdrv/ioport.h>
#include <pbio/port_interface.h>
Expand Down Expand Up @@ -396,6 +397,22 @@ unsigned int EDMAVersionGet(void) {
return 1;
}

void pbdrv_cache_prepare_before_dma(const void *buf, size_t sz) {
// Make sure all data is written by the compiler...
pbdrv_compiler_memory_barrier();
// and then make sure it's written out of the cache...
CP15DCacheCleanBuff((uint32_t)buf, sz);
// and also the write buffer, in case the cache missed.
CP15DrainWriteBuffer();
}

void pbdrv_cache_prepare_after_dma(const void *buf, size_t sz) {
// Invalidate stale data in the cache...
CP15DCacheFlushBuff((uint32_t)buf, sz);
// and then make sure _subsequent_ reads cannot be reordered earlier.
pbdrv_compiler_memory_barrier();
}

static void panic_puts(const char *c) {
while (*c) {
UARTCharPut(SOC_UART_1_REGS, *(c++));
Expand Down
10 changes: 10 additions & 0 deletions lib/tiam1808/system_config/armv5/gcc/cp15.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,16 @@ void CP15DCacheCleanBuff(unsigned int bufPtr, unsigned int size)
}
}

/**
* \brief This function drains the CPU write buffer and acts as a data memory barrier.
*/
void CP15DrainWriteBuffer(void)
{
__asm(" mov r0, #0\n\t"
" mcr p15, #0, r0, c7, c10, #4"
::: "r0");
}

/**
* \brief This API Configures translation table base register with
* with page table starting address.
Expand Down
1 change: 1 addition & 0 deletions lib/tiam1808/tiam1808/armv5/cp15.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ extern void CP15MMUDisable(void);
extern void CP15MMUEnable(void);
extern void CP15DCacheFlushBuff(unsigned int ptr, unsigned int size);
extern void CP15DCacheCleanBuff(unsigned int bufPtr, unsigned int size);
extern void CP15DrainWriteBuffer(void);
extern uint32_t CP15GetDFSR(void);
extern uint32_t CP15GetIFSR(void);
extern uint32_t CP15GetFAR(void);
Expand Down