Skip to content

Commit e0ca607

Browse files
committed
Guard the STM32H7S GFXMMU window with an MPU region while the D-cache is on
1 parent 226a2c7 commit e0ca607

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎docs/Targets.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,23 @@ external memory loader all leave a working configuration behind, so a port
19371937
that omits this appears to boot fine and only fails once power is actually
19381938
removed.
19391939

1940+
### GFXMMU window and the D-cache
1941+
1942+
`0x25000000`-`0x25FFFFFF` holds the GFXMMU virtual buffers. With the GFXMMU
1943+
clock off, which is the reset state, a read in that window never completes:
1944+
no bus error is returned, the core stalls and the debugger can no longer
1945+
halt it. The window is Normal memory in the default memory map, and a
1946+
Cortex-M7 with the D-cache enabled may read Normal memory speculatively, so
1947+
no code has to touch the window on purpose. `hal_init()` therefore sets one
1948+
MPU region marking it no-access before enabling the D-cache.
1949+
`hal_prepare_boot()` turns the caches and the MPU off again so the
1950+
application starts from the reset state.
1951+
1952+
An application that enables the D-cache needs the same protection: either a
1953+
no-access MPU region over the window, or a no-access background region with
1954+
only the memories in use and the peripheral range opened. The background
1955+
region STM32CubeMX generates covers `0x60000000`-`0xDFFFFFFF` only.
1956+
19401957
### Bootloader self-update is off
19411958

19421959
`RAM_CODE` is 0 in the example configuration. It would compile in the

‎hal/stm32h7s.c‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,31 @@ void RAMFUNCTION hal_cache_invalidate(void)
276276
ISB();
277277
}
278278

279+
/* Make the GFXMMU virtual-buffer window inaccessible while the D-cache is
280+
* on. The window is Normal memory in the default map, the core may read
281+
* Normal memory speculatively once the D-cache is enabled, and with the
282+
* GFXMMU clock off such a read stalls the bus for good: no fault, and the
283+
* debugger loses the core. A no-access region stops the read being issued. */
284+
static void mpu_guard_enable(void)
285+
{
286+
MPU_CTRL = 0;
287+
MPU_RNR = 0;
288+
MPU_RBAR = GFXMMU_VBUF_BASE;
289+
MPU_RASR = MPU_RASR_XN | MPU_RASR_SIZE_16MB | MPU_RASR_ENABLE;
290+
MPU_CTRL = MPU_CTRL_PRIVDEFENA | MPU_CTRL_ENABLE;
291+
DSB();
292+
ISB();
293+
}
294+
295+
static void mpu_guard_disable(void)
296+
{
297+
MPU_CTRL = 0;
298+
MPU_RNR = 0;
299+
MPU_RASR = 0;
300+
DSB();
301+
ISB();
302+
}
303+
279304
static void dcache_enable(void)
280305
{
281306
uint32_t sets, ways;
@@ -884,6 +909,7 @@ void hal_init(void)
884909
icache_enable();
885910
octospi_gpio_init();
886911
octospi_init();
912+
mpu_guard_enable();
887913
dcache_enable();
888914
#ifdef DEBUG_UART
889915
uart_init();
@@ -905,6 +931,7 @@ void hal_prepare_boot(void)
905931
octospi_enable_mmap();
906932
dcache_disable();
907933
icache_disable();
934+
mpu_guard_disable();
908935
}
909936

910937
#endif /* !WOLFBOOT_UNIT_TEST_FLASH_ERASE */

‎hal/stm32h7s.h‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,20 @@
454454
#define CCSIDR (*(volatile uint32_t *)(0xE000ED80UL))
455455
#define CSSELR (*(volatile uint32_t *)(0xE000ED84UL))
456456

457+
#define MPU_CTRL (*(volatile uint32_t *)(0xE000ED94UL))
458+
#define MPU_RNR (*(volatile uint32_t *)(0xE000ED98UL))
459+
#define MPU_RBAR (*(volatile uint32_t *)(0xE000ED9CUL))
460+
#define MPU_RASR (*(volatile uint32_t *)(0xE000EDA0UL))
461+
#define MPU_CTRL_ENABLE (1 << 0)
462+
#define MPU_CTRL_PRIVDEFENA (1 << 2)
463+
#define MPU_RASR_ENABLE (1 << 0)
464+
#define MPU_RASR_SIZE_16MB (23 << 1)
465+
#define MPU_RASR_XN (1 << 28)
466+
467+
/* GFXMMU virtual buffers 0..3. A read here never completes while the
468+
* GFXMMU clock is off. */
469+
#define GFXMMU_VBUF_BASE (0x25000000UL)
470+
457471
#define CACHE_LINE_SIZE 32
458472

459473
#endif /* _STM32H7S_DEF_INCLUDED */

0 commit comments

Comments
 (0)