|
28 | 28 |
|
29 | 29 | #include "py/mperrno.h"
|
30 | 30 | #include "py/mphal.h"
|
| 31 | +#include "mpu.h" |
31 | 32 | #include "qspi.h"
|
32 | 33 | #include "pin_static_af.h"
|
33 | 34 |
|
34 | 35 | #if defined(MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2)
|
35 | 36 |
|
| 37 | +#define QSPI_MAP_ADDR (0x90000000) |
| 38 | + |
36 | 39 | #ifndef MICROPY_HW_QSPI_PRESCALER
|
37 | 40 | #define MICROPY_HW_QSPI_PRESCALER 3 // F_CLK = F_AHB/3 (72MHz when CPU is 216MHz)
|
38 | 41 | #endif
|
|
49 | 52 | #define MICROPY_HW_QSPI_CS_HIGH_CYCLES 2 // nCS stays high for 2 cycles
|
50 | 53 | #endif
|
51 | 54 |
|
| 55 | +static inline void qspi_mpu_disable_all(void) { |
| 56 | + // Configure MPU to disable access to entire QSPI region, to prevent CPU |
| 57 | + // speculative execution from accessing this region and modifying QSPI registers. |
| 58 | + mpu_config_start(); |
| 59 | + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_DISABLE(0x00, MPU_REGION_SIZE_256MB)); |
| 60 | + mpu_config_end(); |
| 61 | +} |
| 62 | + |
| 63 | +static inline void qspi_mpu_enable_mapped(void) { |
| 64 | + // Configure MPU to allow access to only the valid part of external SPI flash. |
| 65 | + // The memory accesses to the mapped QSPI are faster if the MPU is not used |
| 66 | + // for the memory-mapped region, so 3 MPU regions are used to disable access |
| 67 | + // to everything except the valid address space, using holes in the bottom |
| 68 | + // of the regions and nesting them. |
| 69 | + // At the moment this is hard-coded to 2MiB of QSPI address space. |
| 70 | + mpu_config_start(); |
| 71 | + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_DISABLE(0x01, MPU_REGION_SIZE_256MB)); |
| 72 | + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_DISABLE(0x0f, MPU_REGION_SIZE_32MB)); |
| 73 | + mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_DISABLE(0x01, MPU_REGION_SIZE_16MB)); |
| 74 | + mpu_config_end(); |
| 75 | +} |
| 76 | + |
52 | 77 | void qspi_init(void) {
|
| 78 | + qspi_mpu_disable_all(); |
| 79 | + |
53 | 80 | // Configure pins
|
54 | 81 | mp_hal_pin_config_alt_static_speed(MICROPY_HW_QSPIFLASH_CS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, MP_HAL_PIN_SPEED_VERY_HIGH, STATIC_AF_QUADSPI_BK1_NCS);
|
55 | 82 | mp_hal_pin_config_alt_static_speed(MICROPY_HW_QSPIFLASH_SCK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, MP_HAL_PIN_SPEED_VERY_HIGH, STATIC_AF_QUADSPI_CLK);
|
@@ -100,6 +127,8 @@ void qspi_memory_map(void) {
|
100 | 127 | | 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
|
101 | 128 | | 0xeb << QUADSPI_CCR_INSTRUCTION_Pos // quad read opcode
|
102 | 129 | ;
|
| 130 | + |
| 131 | + qspi_mpu_enable_mapped(); |
103 | 132 | }
|
104 | 133 |
|
105 | 134 | STATIC int qspi_ioctl(void *self_in, uint32_t cmd) {
|
|
0 commit comments