Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

imx233: make sure dma descriptors are cache friendly

Because DMA descriptors needs to be committed and discarded from
the cache, if they are not cache aligned and/or if their size
is not a multiple of cache ligne, nasty side effects could occur
with adjacents data. The same applies to DMA buffers which are
still potentially broken. Add a macro to ensure that these
constraints will not break by error in the future.

Change-Id: I1dd69a5a9c29796c156d953eaa57c0d281e79846

+34 -7
+6
firmware/export/imx233.h
··· 86 86 /* 32 bytes per cache line */ 87 87 #define CACHEALIGN_BITS 5 88 88 89 + #define ___ENSURE_ZERO(line, x) static uint8_t __ensure_zero_##line[-(x)] __attribute__((unused)); 90 + #define __ENSURE_ZERO(x) ___ENSURE_ZERO(__LINE__, x) 91 + #define __ENSURE_MULTIPLE(x, y) __ENSURE_ZERO((x) % (y)) 92 + #define __ENSURE_CACHELINE_MULTIPLE(x) __ENSURE_MULTIPLE(x, 1 << CACHEALIGN_BITS) 93 + #define __ENSURE_STRUCT_CACHE_FRIENDLY(name) __ENSURE_CACHELINE_MULTIPLE(sizeof(name)) 94 + 89 95 #define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP) 90 96 #define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP) 91 97 #define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP)
+4
firmware/target/arm/imx233/dma-imx233.h
··· 118 118 * COMMON * 119 119 **********/ 120 120 121 + /* DMA structures should be cache aligned and be padded so that their size 122 + * is a multiple of a cache line size. Otherwise some nasty side effects 123 + * could occur with adjacents data fields. 124 + * The same apply to DMA buffers for the same reasons */ 121 125 struct apb_dma_command_t 122 126 { 123 127 struct apb_dma_command_t *next;
+5 -1
firmware/target/arm/imx233/i2c-imx233.c
··· 34 34 struct apb_dma_command_t dma; 35 35 /* PIO words */ 36 36 uint32_t ctrl0; 37 - }; 37 + /* padded to next multiple of cache line size (32 bytes) */ 38 + uint32_t pad[4]; 39 + } __attribute__((packed)) CACHEALIGN_ATTR; 40 + 41 + __ENSURE_STRUCT_CACHE_FRIENDLY(struct i2c_dma_command_t) 38 42 39 43 #define I2C_NR_STAGES 4 40 44 /* Current transfer */
+14 -5
firmware/target/arm/imx233/pcm-imx233.c
··· 26 26 #include "pcm-internal.h" 27 27 #include "audioout-imx233.h" 28 28 29 + struct pcm_dma_command_t 30 + { 31 + struct apb_dma_command_t dma; 32 + /* padded to next multiple of cache line size (32 bytes) */ 33 + uint32_t pad[5]; 34 + } __attribute__((packed)) CACHEALIGN_ATTR; 35 + 36 + __ENSURE_STRUCT_CACHE_FRIENDLY(struct pcm_dma_command_t) 37 + 29 38 static int locked = 0; 30 - static struct apb_dma_command_t dac_dma; 39 + static struct pcm_dma_command_t dac_dma; 31 40 static bool pcm_freezed = false; 32 41 33 42 /** ··· 37 46 38 47 static void play(const void *addr, size_t size) 39 48 { 40 - dac_dma.next = NULL; 41 - dac_dma.buffer = (void *)addr; 42 - dac_dma.cmd = HW_APB_CHx_CMD__COMMAND__READ | 49 + dac_dma.dma.next = NULL; 50 + dac_dma.dma.buffer = (void *)addr; 51 + dac_dma.dma.cmd = HW_APB_CHx_CMD__COMMAND__READ | 43 52 HW_APB_CHx_CMD__IRQONCMPLT | 44 53 HW_APB_CHx_CMD__SEMAPHORE | 45 54 size << HW_APB_CHx_CMD__XFER_COUNT_BP; 46 55 /* dma subsystem will make sure cached stuff is written to memory */ 47 - imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma); 56 + imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma.dma); 48 57 } 49 58 50 59 void INT_DAC_DMA(void)
+5 -1
firmware/target/arm/imx233/ssp-imx233.c
··· 43 43 uint32_t ctrl0; 44 44 uint32_t cmd0; 45 45 uint32_t cmd1; 46 - }; 46 + /* padded to next multiple of cache line size (32 bytes) */ 47 + uint32_t pad[2]; 48 + } __attribute__((packed)) CACHEALIGN_ATTR; 49 + 50 + __ENSURE_STRUCT_CACHE_FRIENDLY(struct ssp_dma_command_t) 47 51 48 52 static bool ssp_in_use[2]; 49 53 static int ssp_nr_in_use = 0;