You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ar...@apache.org on 2025/03/10 05:24:07 UTC
(nuttx) branch master updated: arch/arm/STM32H5: Initial ICACHE Support
This is an automated email from the ASF dual-hosted git repository.
archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 46411495ef arch/arm/STM32H5: Initial ICACHE Support
46411495ef is described below
commit 46411495efed11e1c7fa4b9bec93bb396a0276c8
Author: Kyle Wilson <kw...@2g-eng.com>
AuthorDate: Tue Jan 28 15:36:12 2025 -0600
arch/arm/STM32H5: Initial ICACHE Support
Add support for the STM32H5 ICACHE peripheral. The CortexM33 does not have typical embedded icache and dcache. Instead STM32H5 provides the ICACHE as a separate peripheral that needs to be configured. This commit adds the stm32h5 specific icache driver. This driver named functions like those in <nuttx/cache.h>. However since the CortexM33 does not have cache itself, ARCH_ICACHE is not enabled. Therefore these stm32h5 specific functions were developed.
Signed-off-by: kywwilson11 <kw...@2g-eng.com>
---
arch/arm/src/stm32h5/Kconfig | 246 ++++++++++++++++++
arch/arm/src/stm32h5/Make.defs | 4 +
arch/arm/src/stm32h5/hardware/stm32_icache.h | 107 ++++++++
arch/arm/src/stm32h5/stm32.h | 9 +-
arch/arm/src/stm32h5/stm32_icache.c | 366 +++++++++++++++++++++++++++
arch/arm/src/stm32h5/stm32_icache.h | 158 ++++++++++++
arch/arm/src/stm32h5/stm32_start.c | 5 +
7 files changed, 891 insertions(+), 4 deletions(-)
diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig
index 79514bca10..5ec9f85872 100644
--- a/arch/arm/src/stm32h5/Kconfig
+++ b/arch/arm/src/stm32h5/Kconfig
@@ -31,6 +31,7 @@ config STM32H5_STM32H5XXXX
bool
default n
select ARCH_HAVE_FPU
+ select STM32H5_HAVE_ICACHE
config STM32H5_STM32H56XXX
bool
@@ -55,6 +56,7 @@ config STM32H5_STM32H56XXX
select STM32H5_HAVE_SPI6
select STM32H5_HAVE_USBFS
select STM32H5_HAVE_HSI48
+ select STM32H5_HAVE_ICACHE_REMAP
config STM32H5_STM32H563XX
# STM32H552 and STM32H562 devices documented in RM0439
@@ -226,6 +228,10 @@ config STM32H5_HAVE_HSI48
bool
default n
+config STM32H5_HAVE_ICACHE
+ bool
+ default n
+
config STM32H5_HAVE_LPUART1
bool
default n
@@ -333,6 +339,11 @@ config STM32H5_ETHMAC
select ARCH_HAVE_PHY
select STM32H5_HAVE_PHY_POLLED
+config STM32H5_ICACHE
+ bool "ICACHE"
+ default n
+ depends on STM32H5_HAVE_ICACHE
+
config STM32H5_QSPI1
bool "QSPI1"
default n
@@ -579,6 +590,241 @@ config STM32H5_FLASH_PREFETCH
---help---
Enable FLASH prefetch
+menu "ICACHE Configuration"
+ depends on STM32H5_ICACHE
+
+config STM32H5_ICACHE_MONITOR_EN
+ bool "Enable ICACHE Hit/Miss Counters"
+ default n
+
+config STM32H5_ICACHE_DIRECT
+ bool "Enable 1-Way Direct Mapped Cache (N-Way = default)"
+ default n
+
+menu "ICACHE Interrupt Configuration"
+ depends on STM32H5_ICACHE
+
+config STM32H5_ICACHE_INV_INT
+ bool "Enable interrupts on full invalidation completion."
+ default n
+
+config STM32H5_ICACHE_ERR_INT
+ bool "Enable interrupts on occurrences of cache errors."
+ default n
+
+endmenu # ICACHE Interrupt Configuration
+
+menu "ICACHE Region Configuration"
+ depends on STM32H5_ICACHE
+
+config STM32H5_ICACHE_REGION0
+ bool "Enable Configuration of ICACHE Region 0"
+ default n
+
+config STM32H5_ICACHE_REGION1
+ bool "Enable Configuration of ICACHE Region 1"
+ default n
+
+config STM32H5_ICACHE_REGION2
+ bool "Enable Configuration of ICACHE Region 2"
+ default n
+
+config STM32H5_ICACHE_REGION3
+ bool "Enable Configuration of ICACHE Region 3"
+ default n
+
+menu "Region 0 Configuration"
+ depends on STM32H5_ICACHE_REGION0 && STM32H5_HAVE_ICACHE_REMAP
+
+config STM32H5_ICACHE_REGION0_BADDR
+ hex "ICACHE Region 0 Base Address Bits [28:21]"
+ default 0
+ range 0 255
+ depends on STM32H5_ICACHE_REGION0
+ ---help---
+ Set bits [28:21] of the base address for ICACHE Region 0.
+
+config STM32H5_ICACHE_REGION0_RSIZE
+ int "ICACHE Region 0 Size"
+ default 1
+ range 1 7
+ depends on STM32H5_ICACHE_REGION0
+ ---help---
+ Set the size of Region 0.
+ 1 = 2 Mbytes, 2 = 4 Mbytes, 3 = 8 Mbytes, 4 = 16 Mbytes,
+ 5 = 2 Mbytes, 6 = 64 Mbytes, 7 = 128 Mbytes.
+
+config STM32H5_ICACHE_REGION0_REMAPADDR
+ hex "ICACHE Region 0 Remap Address Bits [31:21]"
+ default 0
+ range 0 2047
+ depends on STM32H5_ICACHE_REGION0
+ ---help---
+ Set bits [31:21] of ICACHE Region 0 Remap Address..
+
+config STM32H5_ICACHE_REGION0_MSTSEL
+ int "ICACHE Region 0 Master Select (0 or 1)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION0
+ ---help---
+ Select ICACHE Region 0 Master 1 (0) or Master 2 (1).
+
+config STM32H5_ICACHE_REGION0_HBURST
+ int "ICACHE Region 0 Output Burst Type (0 = Wrap, 1 = Incr)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION0
+ ---help---
+ Select Wrap (0) or Increment (1) Output Burst Type.
+
+endmenu # Region 0 Configuration
+
+menu "Region 1 Configuration"
+ depends on STM32H5_ICACHE_REGION1 && STM32H5_HAVE_ICACHE_REMAP
+
+config STM32H5_ICACHE_REGION1_BADDR
+ hex "ICACHE Region 1 Base Address Bits [28:21]"
+ default 0
+ range 0 255
+ depends on STM32H5_ICACHE_REGION1
+ ---help---
+ Set bits [28:21] of the base address for ICACHE Region 1.
+
+config STM32H5_ICACHE_REGION1_RSIZE
+ int "ICACHE Region 1 Size"
+ default 1
+ range 1 7
+ depends on STM32H5_ICACHE_REGION1
+ ---help---
+ Set the size of Region 1.
+ 1 = 2 Mbytes, 2 = 4 Mbytes, 3 = 8 Mbytes, 4 = 16 Mbytes,
+ 5 = 2 Mbytes, 6 = 64 Mbytes, 7 = 128 Mbytes.
+
+config STM32H5_ICACHE_REGION1_REMAPADDR
+ hex "ICACHE Region 1 Remap Address Bits [31:21]"
+ default 0
+ range 0 2047
+ depends on STM32H5_ICACHE_REGION1
+ ---help---
+ Set bits [31:21] of ICACHE Region 1 Remap Address..
+
+config STM32H5_ICACHE_REGION1_MSTSEL
+ int "ICACHE Region 1 Master Select (0 or 1)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION1
+ ---help---
+ Select ICACHE Region 1 Master 1 (0) or Master 2 (1).
+
+config STM32H5_ICACHE_REGION1_HBURST
+ int "ICACHE Region 1 Output Burst Type (0 = Wrap, 1 = Incr)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION1
+ ---help---
+ Select Wrap (0) or Increment (1) Output Burst Type.
+
+endmenu # Region 1 Configuration
+
+menu "Region 2 Configuration"
+ depends on STM32H5_ICACHE_REGION2 && STM32H5_HAVE_ICACHE_REMAP
+
+config STM32H5_ICACHE_REGION2_BADDR
+ hex "ICACHE Region 2 Base Address Bits [28:21]"
+ default 0
+ range 0 255
+ depends on STM32H5_ICACHE_REGION2
+ ---help---
+ Set bits [28:21] of the base address for ICACHE Region 2.
+
+config STM32H5_ICACHE_REGION2_RSIZE
+ int "ICACHE Region 2 Size"
+ default 1
+ range 1 7
+ depends on STM32H5_ICACHE_REGION2
+ ---help---
+ Set the size of Region 2.
+ 1 = 2 Mbytes, 2 = 4 Mbytes, 3 = 8 Mbytes, 4 = 16 Mbytes,
+ 5 = 2 Mbytes, 6 = 64 Mbytes, 7 = 128 Mbytes.
+
+config STM32H5_ICACHE_REGION2_REMAPADDR
+ hex "ICACHE Region 2 Remap Address Bits [31:21]"
+ default 0
+ range 0 2047
+ depends on STM32H5_ICACHE_REGION2
+ ---help---
+ Set bits [31:21] of ICACHE Region 2 Remap Address..
+
+config STM32H5_ICACHE_REGION2_MSTSEL
+ int "ICACHE Region 2 Master Select (0 or 1)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION2
+ ---help---
+ Select ICACHE Region 2 Master 1 (0) or Master 2 (1).
+
+config STM32H5_ICACHE_REGION2_HBURST
+ int "ICACHE Region 2 Output Burst Type (0 = Wrap, 1 = Incr)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION2
+ ---help---
+ Select Wrap (0) or Increment (1) Output Burst Type.
+
+endmenu # Region 2 Configuration
+
+menu "Region 3 Configuration"
+ depends on STM32H5_ICACHE_REGION3 && STM32H5_HAVE_ICACHE_REMAP
+
+config STM32H5_ICACHE_REGION3_BADDR
+ hex "ICACHE Region 3 Base Address Bits [28:21]"
+ default 0
+ range 0 255
+ depends on STM32H5_ICACHE_REGION3
+ ---help---
+ Set bits [28:21] of the base address for ICACHE Region 3.
+
+config STM32H5_ICACHE_REGION3_RSIZE
+ int "ICACHE Region 3 Size"
+ default 1
+ range 1 7
+ depends on STM32H5_ICACHE_REGION3
+ ---help---
+ Set the size of Region 3.
+ 1 = 2 Mbytes, 2 = 4 Mbytes, 3 = 8 Mbytes, 4 = 16 Mbytes,
+ 5 = 2 Mbytes, 6 = 64 Mbytes, 7 = 128 Mbytes.
+
+config STM32H5_ICACHE_REGION3_REMAPADDR
+ hex "ICACHE Region 3 Remap Address Bits [31:21]"
+ default 0
+ range 0 2047
+ depends on STM32H5_ICACHE_REGION3
+ ---help---
+ Set bits [31:21] of ICACHE Region 3 Remap Address..
+
+config STM32H5_ICACHE_REGION3_MSTSEL
+ int "ICACHE Region 3 Master Select (0 or 1)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION3
+ ---help---
+ Select ICACHE Region 3 Master 1 (0) or Master 2 (1).
+
+config STM32H5_ICACHE_REGION3_HBURST
+ int "ICACHE Region 3 Output Burst Type (0 = Wrap, 1 = Incr)"
+ default 0
+ range 0 1
+ depends on STM32H5_ICACHE_REGION3
+ ---help---
+ Select Wrap (0) or Increment (1) Output Burst Type.
+
+endmenu # Region 3 Configuration
+
+endmenu # ICACHE Region Configuration
+
+endmenu # ICACHE Configuration
+
config STM32H5_DISABLE_IDLE_SLEEP_DURING_DEBUG
bool "Disable IDLE Sleep (WFI) in debug mode"
default n
diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs
index 1d5586a993..e878d6cb64 100644
--- a/arch/arm/src/stm32h5/Make.defs
+++ b/arch/arm/src/stm32h5/Make.defs
@@ -56,6 +56,10 @@ ifeq ($(STM32H5_FDCAN_CHARDRIVER),y)
CHIP_CSRCS += stm32_fdcan.c
endif
+ifeq ($(CONFIG_STM32H5_ICACHE),y)
+CHIP_CSRCS += stm32_icache.c
+endif
+
ifeq ($(CONFIG_STM32H5_SPI),y)
CHIP_CSRCS += stm32_spi.c
endif
diff --git a/arch/arm/src/stm32h5/hardware/stm32_icache.h b/arch/arm/src/stm32h5/hardware/stm32_icache.h
new file mode 100644
index 0000000000..eb7efc39ca
--- /dev/null
+++ b/arch/arm/src/stm32h5/hardware/stm32_icache.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/hardware/stm32_icache.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_ICACHE_H
+#define __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_ICACHE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "chip.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register Offsets *********************************************************/
+
+#define STM32_ICACHE_CR_OFFSET 0x00 /* ICACHE Control Register Offset */
+#define STM32_ICACHE_SR_OFFSET 0x04 /* ICACHE Status Register Offset */
+#define STM32_ICACHE_IER_OFFSET 0x08 /* ICACHE Interrupt Enable Register Offset */
+#define STM32_ICACHE_FCR_OFFSET 0x0c /* ICACHE Flag Clear Register Offset */
+#define STM32_ICACHE_HMONR_OFFSET 0x10 /* ICACHE Hit Monitor Register Offset */
+#define STM32_ICACHE_MMONR_OFFSET 0x14 /* ICACHE Miss Monitor Register Offset */
+#define STM32_ICACHE_CRR_OFFSET(x) (0x20 + (x << 3)) /* ICACHE Region Configuration Register Offset */
+
+/* Register Addresses *******************************************************/
+
+#define STM32_ICACHE_CR (STM32_ICACHE_BASE + STM32_ICACHE_CR_OFFSET) /* ICACHE Control Register */
+#define STM32_ICACHE_SR (STM32_ICACHE_BASE + STM32_ICACHE_SR_OFFSET) /* ICACHE Status Register */
+#define STM32_ICACHE_IER (STM32_ICACHE_BASE + STM32_ICACHE_IER_OFFSET) /* ICACHE Interrupt Enable Register */
+#define STM32_ICACHE_FCR (STM32_ICACHE_BASE + STM32_ICACHE_FCR_OFFSET) /* ICACHE Flag Clear Register */
+#define STM32_ICACHE_HMONR (STM32_ICACHE_BASE + STM32_ICACHE_HMONR_OFFSET) /* ICACHE Hit Monitor Register */
+#define STM32_ICACHE_MMONR (STM32_ICACHE_BASE + STM32_ICACHE_MMONR_OFFSET) /* ICACHE Miss Monitor Register */
+#define STM32_ICACHE_CRR(x) (STM32_ICACHE_BASE + STM32_ICACHE_CRR_OFFSET(x)) /* ICACHE Region Configuration Register */
+
+/* Register Bitfield Definitions ********************************************/
+
+/* Control Register */
+
+#define ICACHE_CR_EN (1 << 0) /* Enable */
+#define ICACHE_CR_CACHEINV (1 << 1) /* Cache Invalidate */
+#define ICACHE_CR_WAYSEL (1 << 2) /* Associativity Mode Selection */
+#define ICACHE_CR_HITMEN (1 << 16) /* Hit Monitor Enable */
+#define ICACHE_CR_MISSMEN (1 << 17) /* Miss Monitor Enable */
+#define ICACHE_CR_HITMRST (1 << 18) /* Hit Monitor Reset */
+#define ICACHE_CR_MISSMRST (1 << 19) /* Miss Monitor Reset */
+
+/* Status Register */
+
+#define ICACHE_SR_BUSYF (1 << 0) /* Full Invalidate Busy Flag */
+#define ICACHE_SR_BSYENDF (1 << 1) /* Full Invalidate FInished Flag */
+#define ICACHE_SR_ERRF (1 << 2) /* Cache Error Flag */
+
+/* Interrupt Enable Register */
+
+#define ICACHE_IER_BSYENDIE (1 << 1) /* Full Invalidate Finished Interrupt Enable */
+#define ICACHE_IER_ERRIE (1 << 2) /* Cache Error Interrupt Enable */
+
+#define ICACHE_IER_ALLINTS (ICACHE_IER_BSYENDIE | ICACHE_IER_ERRIE) /* All Cache Interrupts Mask */
+
+/* Flag Clear Register */
+
+#define ICACHE_FCR_CBSYENDF (1 << 1) /* Clear Full Invalidate Finished Flag */
+#define ICACHE_FCR_CERRF (1 << 2) /* Clear Cache Error Flag */
+
+/* Hit Monitor Register */
+
+/* Miss Monitor Register */
+
+#define ICACHE_MMONR_MISSMON_MASK (0xffff) /* 16-bit Miss Monitor Mask */
+
+/* Region x Configuration Register */
+
+#define ICACHE_CRR_BASEADDR_SHIFT (0) /* Base Address for Region x */
+#define ICACHE_CRR_BASEADDR_MASK (0xff << ICACHE_CRR_BASEADDR_SHIFT)
+#define ICACHE_CRR_RSIZE_SHIFT (9) /* Size for Region x (n=1..7, 2^(11+n)) */
+#define ICACHE_CRR_RSIZE_MASK (0x7 << ICACHE_CRR_RSIZE_SHIFT)
+#define ICACHE_CRR_REN (1 << 15)
+#define ICACHE_CRR_REMAPADDR_SHIFT (16) /* Remapped Address for Region x */
+#define ICACHE_CRR_REMAPADDR_MASK (0x7ff << ICACHE_CRR_REMAPADDR_SHIFT)
+#define ICACHE_CRR_MSTSEL_SHIFT (28) /* AHB Cache Master Selection for Region x */
+#define ICACHE_CRR_MSTSEL (1 << ICACHE_CRR_MSTSEL_SHIFT)
+#define ICACHE_CRR_HBURST_SHIFT (31) /* Output Burst Type for Region x (0=Wrap, 1=INCR) */
+#define ICACHE_CRR_HBURST (1 << ICACHE_CRR_HBURST_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_ICACHE_H */
diff --git a/arch/arm/src/stm32h5/stm32.h b/arch/arm/src/stm32h5/stm32.h
index 172499e725..502f8420c7 100644
--- a/arch/arm/src/stm32h5/stm32.h
+++ b/arch/arm/src/stm32h5/stm32.h
@@ -37,15 +37,16 @@
/* Peripherals **************************************************************/
#include "chip.h"
-#include "stm32_flash.h"
+#include "stm32_adc.h"
#include "stm32_dbgmcu.h"
+#include "stm32_flash.h"
#include "stm32_gpio.h"
+#include "stm32_i2c.h"
+#include "stm32_icache.h"
+#include "stm32_lowputc.h"
#include "stm32_pwr.h"
#include "stm32_rcc.h"
#include "stm32_uart.h"
-#include "stm32_lowputc.h"
-#include "stm32_i2c.h"
-#include "stm32_adc.h"
#include "stm32_usbfs.h"
#endif /* __ARCH_ARM_SRC_STM32H5_STM32_H */
diff --git a/arch/arm/src/stm32h5/stm32_icache.c b/arch/arm/src/stm32h5/stm32_icache.c
new file mode 100644
index 0000000000..8cd9c0483e
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_icache.c
@@ -0,0 +1,366 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_icache.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/spinlock.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "arm_internal.h"
+#include "stm32.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define STM32H5_ICACHE_INTERRUPT (defined(CONFIG_STM32H5_ICACHE_INV_INT) ||\
+ defined(CONFIG_STM32H5_ICACHE_ERR_INT))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct stm32_icache_s
+{
+ uint32_t ier; /* Saved interrupt mask bits value */
+
+ /* Has been initialized and HW is setup. */
+
+ bool initialized;
+
+ volatile uint32_t invalidate;
+ volatile uint32_t invalidate_finished;
+ spinlock_t lock;
+};
+
+struct stm32_icache_region
+{
+ uint8_t num;
+ uint8_t baseaddr;
+ uint8_t rsize;
+ uint16_t remapaddr;
+ uint8_t mstsel;
+ uint8_t hburst;
+};
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+static struct stm32_icache_s icache1 =
+{
+ .ier = 0x0,
+ .initialized = false,
+ .invalidate_finished = 0,
+ .lock = SP_UNLOCKED,
+};
+
+#ifdef CONFIG_STM32H5_ICACHE_REGION0
+static struct stm32_icache_region region0 =
+{
+ .num = 0,
+ .baseaddr = CONFIG_STM32H5_ICACHE_REGION0_BADDR,
+ .rsize = CONFIG_STM32H5_ICACHE_REGION0_RSIZE,
+ .remapaddr = CONFIG_STM32H5_ICACHE_REGION0_REMAPADDR,
+ .mstsel = CONFIG_STM32H5_ICACHE_REGION0_MSTSEL,
+ .hburst = CONFIG_STM32H5_ICACHE_REGION0_HBURST,
+};
+#endif
+
+#ifdef CONFIG_STM32H5_ICACHE_REGION1
+static struct stm32_icache_region region1 =
+{
+ .num = 1,
+ .baseaddr = CONFIG_STM32H5_ICACHE_REGION1_BADDR,
+ .rsize = CONFIG_STM32H5_ICACHE_REGION1_RSIZE,
+ .remapaddr = CONFIG_STM32H5_ICACHE_REGION1_REMAPADDR,
+ .mstsel = CONFIG_STM32H5_ICACHE_REGION1_MSTSEL,
+ .hburst = CONFIG_STM32H5_ICACHE_REGION1_HBURST,
+};
+#endif
+
+#ifdef CONFIG_STM32H5_ICACHE_REGION2
+static struct stm32_icache_region region2 =
+{
+ .num = 2,
+ .baseaddr = CONFIG_STM32H5_ICACHE_REGION2_BADDR,
+ .rsize = CONFIG_STM32H5_ICACHE_REGION2_RSIZE,
+ .remapaddr = CONFIG_STM32H5_ICACHE_REGION2_REMAPADDR,
+ .mstsel = CONFIG_STM32H5_ICACHE_REGION2_MSTSEL,
+ .hburst = CONFIG_STM32H5_ICACHE_REGION2_HBURST,
+};
+#endif
+
+#ifdef CONFIG_STM32H5_ICACHE_REGION3
+static struct stm32_icache_region region3 =
+{
+ .num = 3,
+ .baseaddr = CONFIG_STM32H5_ICACHE_REGION3_BADDR,
+ .rsize = CONFIG_STM32H5_ICACHE_REGION3_RSIZE,
+ .remapaddr = CONFIG_STM32H5_ICACHE_REGION3_REMAPADDR,
+ .mstsel = CONFIG_STM32H5_ICACHE_REGION3_MSTSEL,
+ .hburst = CONFIG_STM32H5_ICACHE_REGION3_HBURST,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline void stm32_icache_interrupt(int irq, void *context, void *arg)
+{
+ uint32_t sr = getreg32(STM32_ICACHE_SR);
+
+ if ((icache1.ier & ICACHE_IER_BSYENDIE) && (sr & ICACHE_SR_BSYENDF))
+ {
+ putreg32(ICACHE_FCR_CBSYENDF, STM32_ICACHE_FCR);
+ icache1.invalidate_finished = true;
+ }
+
+ if ((icache1.ier & ICACHE_IER_ERRIE) && (sr & ICACHE_SR_ERRF))
+ {
+ /* Clear Error Flag */
+
+ putreg32(ICACHE_FCR_CERRF, STM32_ICACHE_FCR);
+ }
+}
+
+static inline void stm32_icache_invf_poll(void)
+{
+ while (!(getreg32(STM32_ICACHE_SR) & ICACHE_SR_BSYENDF))
+ {
+ }
+
+ putreg32(ICACHE_FCR_CBSYENDF, STM32_ICACHE_FCR);
+ icache1.invalidate_finished = true;
+}
+
+static inline void stm32_icache_invf_interrupt(void)
+{
+ while (!(icache1.invalidate_finished))
+ {
+ }
+
+ /* Report invalidate is finished */
+}
+
+static inline void stm32_icache_set_ier(uint32_t ier)
+{
+ icache1.ier = ier & ICACHE_IER_ALLINTS;
+ putreg32(icache1.ier, STM32_ICACHE_IER);
+}
+
+static inline void stm32_icache_reset_hmon(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= ICACHE_CR_HITMRST;
+ putreg32(regval, STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_HITMRST);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+static inline void stm32_icache_reset_mmon(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= ICACHE_CR_MISSMRST;
+ putreg32(regval, STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_MISSMRST);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+static inline void stm32_icache_enable_monitors(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= (ICACHE_CR_MISSMEN | ICACHE_CR_HITMEN);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+static inline void stm32_icache_disable_monitors(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_MISSMEN | ICACHE_CR_HITMEN);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+static void stm32_icache_setup_region(struct stm32_icache_region region)
+{
+ uint32_t regval = 0;
+
+ regval |= (region.baseaddr << ICACHE_CRR_BASEADDR_SHIFT);
+ regval |= ((region.rsize << ICACHE_CRR_RSIZE_SHIFT) & \
+ ICACHE_CRR_RSIZE_MASK);
+ regval |= ICACHE_CRR_REN;
+ regval |= ((region.remapaddr << ICACHE_CRR_REMAPADDR_SHIFT) & \
+ ICACHE_CRR_REMAPADDR_MASK);
+ regval |= (region.mstsel << ICACHE_CRR_MSTSEL_SHIFT);
+ regval |= (region.hburst << ICACHE_CRR_HBURST_SHIFT);
+
+ putreg32(regval, STM32_ICACHE_CRR(region.num));
+}
+
+void stm32_icache_initialize(void)
+{
+ uint32_t regval;
+
+ /* Set associativity */
+
+#ifdef CONFIG_STM32H5_ICACHE_DIRECT
+ regval = getreg32(STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_WAYSEL);
+ putreg32(regval, STM32_ICACHE_CR);
+#endif
+
+/* Enable Hit/Miss Monitors
+ * Use CONFIG options to Enable Hit/Miss
+ * Reset Monitors on Initialization
+ */
+
+#ifdef CONFIG_STM32H5_ICACHE_MONITOR_EN
+ stm32_icache_enable_monitors();
+ stm32_icache_reset_monitors();
+#endif
+
+ /* Set up region configuration registers */
+
+#ifdef CONFIG_STM32H5_ICACHE_REGION0
+ stm32_icache_setup_region(region0);
+#endif
+#ifdef CONFIG_STM32H5_ICACHE_REGION1
+ stm32_icache_setup_region(region1);
+#endif
+#ifdef CONFIG_STM32H5_ICACHE_REGION2
+ stm32_icache_setup_region(region2);
+#endif
+#ifdef CONFIG_STM32H5_ICACHE_REGION3
+ stm32_icache_setup_region(region3);
+#endif
+
+#if STM32H5_ICACHE_INTERRUPT
+ /* Attach ISR */
+
+ int ret;
+
+ ret = irq_attach(STM32_IRQ_ICACHE, (xcpt_t) stm32_icache_interrupt, NULL);
+
+ /* Enable Interrupts */
+
+ if (ret == OK)
+ {
+ regval = 0;
+# ifdef CONFIG_STM32H5_ICACHE_INV_INT
+ regval |= ICACHE_IER_BSYENDIE;
+# endif
+# ifdef CONFIG_STM32H5_ICACHE_ERR_INT
+ regval |= ICACHE_IER_ERRIE;
+# endif
+ stm32_icache_set_ier(regval);
+
+ up_enable_irq(STM32_IRQ_ICACHE);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void stm32_icache_reset_monitors(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= (ICACHE_CR_MISSMRST | ICACHE_CR_HITMRST);
+ putreg32(regval, STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_MISSMRST | ICACHE_CR_HITMRST);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+size_t stm32_get_icache_linesize(void)
+{
+ return 16;
+}
+
+size_t stm32_get_icache_size(void)
+{
+ return 8192;
+}
+
+void stm32_disable_icache(void)
+{
+ uint32_t regval;
+ regval = getreg32(STM32_ICACHE_CR);
+ regval &= ~(ICACHE_CR_EN);
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+void stm32_enable_icache(void)
+{
+ uint32_t regval;
+
+ if (icache1.initialized != true)
+ {
+ stm32_icache_initialize();
+ icache1.initialized = true;
+ }
+
+ /* Enable the ICACHE */
+
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= ICACHE_CR_EN;
+ putreg32(regval, STM32_ICACHE_CR);
+}
+
+void stm32_invalidate_icache(void)
+{
+ uint32_t regval;
+
+ /* Preemptively clear BSYENDF */
+
+ putreg32(ICACHE_FCR_CBSYENDF, STM32_ICACHE_FCR);
+
+ /* Set invalidate finished to false */
+
+ icache1.invalidate_finished = false;
+
+ /* Start the icache invalidate process */
+
+ regval = getreg32(STM32_ICACHE_CR);
+ regval |= ICACHE_CR_CACHEINV;
+ putreg32(regval, STM32_ICACHE_CR);
+
+#if defined(CONFIG_STM32H5_ICACHE_INV_INT)
+ stm32_icache_invf_interrupt();
+#else
+ stm32_icache_invf_poll();
+#endif
+}
diff --git a/arch/arm/src/stm32h5/stm32_icache.h b/arch/arm/src/stm32h5/stm32_icache.h
new file mode 100644
index 0000000000..13684c4f26
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_icache.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_icache.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32H5_STM32_ICACHE_H
+#define __ARCH_ARM_SRC_STM32H5_STM32_ICACHE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+
+#include "chip.h"
+#include "hardware/stm32_icache.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_get_icache_linesize
+ *
+ * Description:
+ * Returns the icache linesize.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * 16
+ *
+ ****************************************************************************/
+
+size_t stm32_get_icache_linesize(void);
+
+/****************************************************************************
+ * Name: stm32_get_icache_size
+ *
+ * Description:
+ * Returns the icache size.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * 8192
+ *
+ ****************************************************************************/
+
+size_t stm32_get_icache_size(void);
+
+/****************************************************************************
+ * Name: stm32_enable_icache
+ *
+ * Description:
+ * Initializes the STM32H5 ICACHE
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void stm32_enable_icache(void);
+
+/****************************************************************************
+ * Name: stm32_disable_icache
+ *
+ * Description:
+ * Disables the STM32H5 ICACHE.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void stm32_disable_icache(void);
+
+/****************************************************************************
+ * Name: stm32_reset_monitors
+ *
+ * Description:
+ * Reset the ICACHE Hit and Miss Counters
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void stm32_icache_reset_monitors(void);
+
+/****************************************************************************
+ * Name: stm32_invalidate_icache
+ *
+ * Description:
+ * Invalidate the icache and wait for its completion.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void stm32_invalidate_icache(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32H5_STM32_ICACHE_H */
diff --git a/arch/arm/src/stm32h5/stm32_start.c b/arch/arm/src/stm32h5/stm32_start.c
index 348004f1c2..b50837ec8c 100644
--- a/arch/arm/src/stm32h5/stm32_start.c
+++ b/arch/arm/src/stm32h5/stm32_start.c
@@ -229,6 +229,11 @@ void __start(void)
stm32_board_initialize();
showprogress('F');
+#ifdef CONFIG_STM32H5_ICACHE
+ stm32_enable_icache();
+#endif
+ showprogress('G');
+
/* Then start NuttX */
showprogress('\r');