Skip to content

Commit c8b3c52

Browse files
committed
pbio/include/pbdrv/cache.h: Add header for cache ops
1 parent 3f0a951 commit c8b3c52

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

lib/pbio/include/pbdrv/cache.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025 The Pybricks Authors
3+
4+
#ifndef _PBDRV_CACHE_H_
5+
6+
#include <stddef.h>
7+
8+
// Gets data ready so that the data that we (the CPU) have written
9+
// can be read by DMA peripherals. This cleans the relevant cache lines
10+
// and flushes the write buffer.
11+
void pbdrv_cache_prepare_before_dma(const void *buf, size_t sz);
12+
13+
// Makes sure that we (the CPU) are able to read data written
14+
// by DMA peripherals. This invalidates the relevant cache lines.
15+
void pbdrv_cache_prepare_after_dma(const void *buf, size_t sz);
16+
17+
// Accesses a variable via the uncached memory alias
18+
#define PBDRV_UNCACHED(x) (*(volatile __typeof__(x) *)((uint32_t)(&(x)) + 0x10000000))
19+
20+
// Gets the address of the uncached memory alias of a variable
21+
#define PBDRV_UNCACHED_ADDR(x) ((__typeof__(x) *)((uint32_t)(&(x)) + 0x10000000))
22+
23+
// Cache line size
24+
#define PBDRV_CACHE_LINE_SZ 32
25+
26+
// Align data to a cache line, which is needed for clean RX DMA
27+
#define PBDRV_CACHE_LINE_ALIGNED __attribute__((aligned(PBDRV_CACHE_LINE_SZ)))
28+
29+
#endif

lib/pbio/platform/ev3/platform.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
#include <umm_malloc.h>
5757

58+
#include <pbdrv/cache.h>
5859
#include <pbdrv/compiler.h>
5960
#include <pbdrv/ioport.h>
6061
#include <pbio/port_interface.h>
@@ -396,6 +397,22 @@ unsigned int EDMAVersionGet(void) {
396397
return 1;
397398
}
398399

400+
void pbdrv_cache_prepare_before_dma(const void *buf, size_t sz) {
401+
// Make sure all data is written by the compiler...
402+
pbdrv_compiler_memory_barrier();
403+
// and then make sure it's written out of the cache...
404+
CP15DCacheCleanBuff((uint32_t)buf, sz);
405+
// and also the write buffer, in case the cache missed.
406+
CP15DrainWriteBuffer();
407+
}
408+
409+
void pbdrv_cache_prepare_after_dma(const void *buf, size_t sz) {
410+
// Invalidate stale data in the cache...
411+
CP15DCacheFlushBuff((uint32_t)buf, sz);
412+
// and then make sure _subsequent_ reads cannot be reordered earlier.
413+
pbdrv_compiler_memory_barrier();
414+
}
415+
399416
static void panic_puts(const char *c) {
400417
while (*c) {
401418
UARTCharPut(SOC_UART_1_REGS, *(c++));

lib/tiam1808/system_config/armv5/gcc/cp15.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ void CP15DCacheCleanBuff(unsigned int bufPtr, unsigned int size)
208208
}
209209
}
210210

211+
/**
212+
* \brief This function drains the CPU write buffer and acts as a data memory barrier.
213+
*/
214+
void CP15DrainWriteBuffer(void)
215+
{
216+
__asm(" mov r0, #0\n\t"
217+
" mcr p15, #0, r0, c7, c10, #4"
218+
::: "r0");
219+
}
220+
211221
/**
212222
* \brief This API Configures translation table base register with
213223
* with page table starting address.

lib/tiam1808/tiam1808/armv5/cp15.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ extern void CP15MMUDisable(void);
6262
extern void CP15MMUEnable(void);
6363
extern void CP15DCacheFlushBuff(unsigned int ptr, unsigned int size);
6464
extern void CP15DCacheCleanBuff(unsigned int bufPtr, unsigned int size);
65+
extern void CP15DrainWriteBuffer(void);
6566
extern uint32_t CP15GetDFSR(void);
6667
extern uint32_t CP15GetIFSR(void);
6768
extern uint32_t CP15GetFAR(void);

0 commit comments

Comments
 (0)