From 7761387ba0a0ac206b7e5ab133462c29882b63bd Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 8 Jan 2018 08:58:34 +0000 Subject: Added unified cache handler for Cortex-M devices. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11233 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/BDMAv1/notes.txt | 6 +- os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h | 30 +----- os/hal/ports/STM32/LLD/DMAv2/notes.txt | 2 - os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h | 71 +------------ os/hal/ports/STM32/LLD/DMAv3/notes.txt | 2 - os/hal/ports/STM32/LLD/DMAv3/stm32_dma.h | 70 +------------ os/hal/ports/STM32/STM32F4xx/stm32_registry.h | 24 ----- os/hal/ports/STM32/STM32F7xx/stm32_registry.h | 3 - os/hal/ports/STM32/STM32H7xx/stm32_registry.h | 2 - os/hal/ports/common/ARMCMx/cache.h | 138 ++++++++++++++++++++++++++ testhal/STM32/multi/SPI/main.c | 10 +- 11 files changed, 150 insertions(+), 208 deletions(-) create mode 100644 os/hal/ports/common/ARMCMx/cache.h diff --git a/os/hal/ports/STM32/LLD/BDMAv1/notes.txt b/os/hal/ports/STM32/LLD/BDMAv1/notes.txt index 70847016e..e7fe3ad1f 100644 --- a/os/hal/ports/STM32/LLD/BDMAv1/notes.txt +++ b/os/hal/ports/STM32/LLD/BDMAv1/notes.txt @@ -6,8 +6,6 @@ Driver capability: The file registry must export: -STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro +STM32_BDMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro is not exported then the ISR is not declared. -STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7). -STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache - handling on DMA buffers. \ No newline at end of file +STM32_BDMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7). diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h index 5034a32ab..ffa438003 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h @@ -27,6 +27,8 @@ #ifndef STM32_DMA_H #define STM32_DMA_H +#include "cache.h" + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -258,34 +260,6 @@ typedef struct { /* Driver macros. */ /*===========================================================================*/ -/** - * @brief Invalidates the data cache lines overlapping a DMA buffer. - * @note It does nothing in this driver, it is supplied for compatibility. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferInvalidate(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} - -/** - * @brief Flushes the data cache lines overlapping a DMA buffer. - * @note It does nothing in this driver, it is supplied for compatibility. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferFlush(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} - /** * @name Macro Functions * @{ diff --git a/os/hal/ports/STM32/LLD/DMAv2/notes.txt b/os/hal/ports/STM32/LLD/DMAv2/notes.txt index a4e14d38d..4c01d8309 100644 --- a/os/hal/ports/STM32/LLD/DMAv2/notes.txt +++ b/os/hal/ports/STM32/LLD/DMAv2/notes.txt @@ -16,5 +16,3 @@ STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other STM32_HAS_DMAx - Support for DMA unit "x" (1..2). STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7). STM32_DMAn_CHx_NUMBER - Vector number for channel "n" (0..7). -STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache - handling on DMA buffers. \ No newline at end of file diff --git a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h index 4e714ad49..112af2e80 100644 --- a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h @@ -25,6 +25,8 @@ #ifndef STM32_DMA_H #define STM32_DMA_H +#include "cache.h" + /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -216,10 +218,6 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#if !defined(STM32_DMA_CACHE_HANDLING) -#error "STM32_DMA_CACHE_HANDLING missing in registry" -#endif - #if !defined(STM32_HAS_DMA1) #error "STM32_HAS_DMA1 missing in registry" #endif @@ -385,71 +383,6 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ -#if STM32_DMA_CACHE_HANDLING || defined(__DOXYGEN__) -/** - * @brief Invalidates the data cache lines overlapping a DMA buffer. - * @details This function is meant to make sure that data written in - * data cache is invalidated. It is used for DMA buffers that - * must have been written by a DMA stream. - * @note On devices without data cache this function does nothing. - * @note The function does not consider the lower 5 bits of addresses, - * the buffers are meant to be aligned to a 32 bytes boundary or - * adjacent data can be invalidated as side effect. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferInvalidate(saddr, n) { \ - uint8_t *start = (uint8_t *)(saddr); \ - uint8_t *end = start + (size_t)(n); \ - __DSB(); \ - while (start < end) { \ - SCB->DCIMVAC = (uint32_t)start; \ - start += 32U; \ - } \ - __DSB(); \ - __ISB(); \ -} - -/** - * @brief Flushes the data cache lines overlapping a DMA buffer. - * @details This function is meant to make sure that data written in - * data cache is flushed to RAM. It is used for DMA buffers that - * must be read by a DMA stream. - * @note On devices without data cache this function does nothing. - * @note The function does not consider the lower 5 bits of addresses, - * the buffers are meant to be aligned to a 32 bytes boundary or - * adjacent data can be flushed as side effect. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferFlush(saddr, n) { \ - uint8_t *start = (uint8_t *)(saddr); \ - uint8_t *end = start + (size_t)(n); \ - __DSB(); \ - while (start < end) { \ - SCB->DCCIMVAC = (uint32_t)start; \ - start += 32U; \ - } \ - __DSB(); \ - __ISB(); \ -} -#else -#define dmaBufferInvalidate(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} -#define dmaBufferFlush(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} -#endif - /** * @name Macro Functions * @{ diff --git a/os/hal/ports/STM32/LLD/DMAv3/notes.txt b/os/hal/ports/STM32/LLD/DMAv3/notes.txt index 556a2cc72..9004cd3f1 100644 --- a/os/hal/ports/STM32/LLD/DMAv3/notes.txt +++ b/os/hal/ports/STM32/LLD/DMAv3/notes.txt @@ -10,5 +10,3 @@ The file registry must export: STM32_HAS_DMAx - Support for DMA unit "x" (1..2). STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7). STM32_DMAx_CHn_NUMBER - Vector number for channel "n" (0..7). -STM32_DMA_CACHE_HANDLING - TRUE if the device requires explicit cache - handling on DMA buffers. \ No newline at end of file diff --git a/os/hal/ports/STM32/LLD/DMAv3/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv3/stm32_dma.h index ff9e19538..f6208f9e8 100644 --- a/os/hal/ports/STM32/LLD/DMAv3/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv3/stm32_dma.h @@ -25,6 +25,7 @@ #ifndef STM32_DMA_H #define STM32_DMA_H +#include "cache.h" #include "stm32_dmamux.h" /*===========================================================================*/ @@ -171,10 +172,6 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#if !defined(STM32_DMA_CACHE_HANDLING) -#error "STM32_DMA_CACHE_HANDLING missing in registry" -#endif - #if !defined(STM32_HAS_DMA1) #error "STM32_HAS_DMA1 missing in registry" #endif @@ -341,71 +338,6 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ -#if STM32_DMA_CACHE_HANDLING || defined(__DOXYGEN__) -/** - * @brief Invalidates the data cache lines overlapping a DMA buffer. - * @details This function is meant to make sure that data written in - * data cache is invalidated. It is used for DMA buffers that - * must have been written by a DMA stream. - * @note On devices without data cache this function does nothing. - * @note The function does not consider the lower 5 bits of addresses, - * the buffers are meant to be aligned to a 32 bytes boundary or - * adjacent data can be invalidated as side effect. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferInvalidate(saddr, n) { \ - uint8_t *start = (uint8_t *)(saddr); \ - uint8_t *end = start + (size_t)(n); \ - __DSB(); \ - while (start < end) { \ - SCB->DCIMVAC = (uint32_t)start; \ - start += 32U; \ - } \ - __DSB(); \ - __ISB(); \ -} - -/** - * @brief Flushes the data cache lines overlapping a DMA buffer. - * @details This function is meant to make sure that data written in - * data cache is flushed to RAM. It is used for DMA buffers that - * must be read by a DMA stream. - * @note On devices without data cache this function does nothing. - * @note The function does not consider the lower 5 bits of addresses, - * the buffers are meant to be aligned to a 32 bytes boundary or - * adjacent data can be flushed as side effect. - * - * @param[in] saddr start address of the DMA buffer - * @param[in] n size of the DMA buffer in bytes - * - * @api - */ -#define dmaBufferFlush(saddr, n) { \ - uint8_t *start = (uint8_t *)(saddr); \ - uint8_t *end = start + (size_t)(n); \ - __DSB(); \ - while (start < end) { \ - SCB->DCCIMVAC = (uint32_t)start; \ - start += 32U; \ - } \ - __DSB(); \ - __ISB(); \ -} -#else -#define dmaBufferInvalidate(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} -#define dmaBufferFlush(addr, size) { \ - (void)(addr); \ - (void)(size); \ -} -#endif - /** * @name Macro Functions * @{ diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h index 8d663aef7..cf0438fcc 100644 --- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h @@ -130,9 +130,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -501,9 +498,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -847,9 +841,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -1200,9 +1191,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -1523,9 +1511,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -1824,9 +1809,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -2104,9 +2086,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 @@ -2441,9 +2420,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING FALSE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h index 03797e13f..1da275bc9 100644 --- a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h @@ -111,9 +111,6 @@ #define STM32_HAS_DAC2_CH2 FALSE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA TRUE -#define STM32_DMA_CACHE_HANDLING TRUE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 diff --git a/os/hal/ports/STM32/STM32H7xx/stm32_registry.h b/os/hal/ports/STM32/STM32H7xx/stm32_registry.h index 0a4af9460..8bee2a7d7 100644 --- a/os/hal/ports/STM32/STM32H7xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32H7xx/stm32_registry.h @@ -87,8 +87,6 @@ #define STM32_BDMA1_CH7_NUMBER 136 /* DMA attributes.*/ -#define STM32_DMA_CACHE_HANDLING TRUE - #define STM32_HAS_DMA1 TRUE #define STM32_DMA1_CH0_HANDLER Vector6C #define STM32_DMA1_CH1_HANDLER Vector70 diff --git a/os/hal/ports/common/ARMCMx/cache.h b/os/hal/ports/common/ARMCMx/cache.h new file mode 100644 index 000000000..73fffe7d0 --- /dev/null +++ b/os/hal/ports/common/ARMCMx/cache.h @@ -0,0 +1,138 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file common/ARMCMx/cache.h + * @brief Cortex-Mx cache support macros and structures. + * + * @addtogroup COMMON_ARMCMx_CACHE + * @{ + */ + +#ifndef CACHE_H +#define CACHE_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#if defined(__DCACHE_PRESENT) || defined(__DOXYGEN__) +#if (__DCACHE_PRESENT != 0) || defined(__DOXYGEN__) +/** + * @brief Invalidates the data cache lines overlapping a memory buffer. + * @details This function is meant to make sure that data written in + * data cache is invalidated. + * @note On devices without data cache this function does nothing. + * @note The function does not consider the lower 5 bits of addresses, + * the buffers are meant to be aligned to a 32 bytes boundary or + * adjacent data can be invalidated as side effect. + * + * @param[in] saddr start address of the DMA buffer + * @param[in] n size of the DMA buffer in bytes + * + * @api + */ +#define cacheBufferInvalidate(saddr, n) { \ + uint8_t *start = (uint8_t *)(saddr); \ + uint8_t *end = start + (size_t)(n); \ + __DSB(); \ + while (start < end) { \ + SCB->DCIMVAC = (uint32_t)start; \ + start += 32U; \ + } \ + __DSB(); \ + __ISB(); \ +} + +/** + * @brief Flushes the data cache lines overlapping a DMA buffer. + * @details This function is meant to make sure that data written in + * data cache is flushed to RAM. + * @note On devices without data cache this function does nothing. + * @note The function does not consider the lower 5 bits of addresses, + * the buffers are meant to be aligned to a 32 bytes boundary or + * adjacent data can be flushed as side effect. + * + * @param[in] saddr start address of the DMA buffer + * @param[in] n size of the DMA buffer in bytes + * + * @api + */ +#define cacheBufferFlush(saddr, n) { \ + uint8_t *start = (uint8_t *)(saddr); \ + uint8_t *end = start + (size_t)(n); \ + __DSB(); \ + while (start < end) { \ + SCB->DCCIMVAC = (uint32_t)start; \ + start += 32U; \ + } \ + __DSB(); \ + __ISB(); \ +} + +#else /* __DCACHE_PRESENT == 0 */ +#define dmaBufferInvalidate(addr, size) { \ + (void)(addr); \ + (void)(size); \ +} +#define dmaBufferFlush(addr, size) { \ + (void)(addr); \ + (void)(size); \ +} +#endif + +#else /* !defined(__DCACHE_PRESENT) */ +#define dmaBufferInvalidate(addr, size) { \ + (void)(addr); \ + (void)(size); \ +} +#define dmaBufferFlush(addr, size) { \ + (void)(addr); \ + (void)(size); \ +} +#endif + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CACHE_H */ + +/** @} */ diff --git a/testhal/STM32/multi/SPI/main.c b/testhal/STM32/multi/SPI/main.c index 852f5107b..85328a6a3 100755 --- a/testhal/STM32/multi/SPI/main.c +++ b/testhal/STM32/multi/SPI/main.c @@ -42,8 +42,8 @@ static THD_FUNCTION(spi_thread_1, p) { spiExchange(&PORTAB_SPI1, 512, txbuf, rxbuf); /* Atomic transfer operations. */ spiUnselect(&PORTAB_SPI1); /* Slave Select de-assertion. */ - dmaBufferInvalidate(&txbuf[0], /* Cache invalidation over the */ - sizeof txbuf); /* buffer. */ + cacheBufferInvalidate(&txbuf[0], /* Cache invalidation over the */ + sizeof txbuf);/* buffer. */ spiReleaseBus(&PORTAB_SPI1); /* Ownership release. */ } } @@ -64,8 +64,8 @@ static THD_FUNCTION(spi_thread_2, p) { spiExchange(&PORTAB_SPI1, 512, txbuf, rxbuf); /* Atomic transfer operations. */ spiUnselect(&PORTAB_SPI1); /* Slave Select de-assertion. */ - dmaBufferInvalidate(&txbuf[0], /* Cache invalidation over the */ - sizeof txbuf); /* buffer. */ + cacheBufferInvalidate(&txbuf[0], /* Cache invalidation over the */ + sizeof txbuf);/* buffer. */ spiReleaseBus(&PORTAB_SPI1); /* Ownership release. */ } } @@ -112,7 +112,7 @@ int main(void) { */ for (i = 0; i < sizeof(txbuf); i++) txbuf[i] = (uint8_t)i; - dmaBufferFlush(&txbuf[0], sizeof txbuf); + cacheBufferFlush(&txbuf[0], sizeof txbuf); /* * Starting the transmitter and receiver threads. -- cgit v1.2.3