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 <kwilson@2g-eng.com>
This commit is contained in:
Kyle Wilson
2025-01-28 15:36:12 -06:00
committed by archer
parent fa5590d5b1
commit 46411495ef
7 changed files with 891 additions and 4 deletions
+246
View File
@@ -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
+4
View File
@@ -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
@@ -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 */
+5 -4
View File
@@ -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 */
+366
View File
@@ -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
}
+158
View File
@@ -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 */
+5
View File
@@ -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');