mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
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:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user