114 lines
3.1 KiB
C
114 lines
3.1 KiB
C
|
/*
|
||
|
* Copyright (C) 2023 Daniele Lacamera <root@danielinux.net>
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
*
|
||
|
* Author: Daniele Lacamera <root@danielinux.net>
|
||
|
*/
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#define MPU_BASE (0xE000ED90)
|
||
|
extern uint32_t _end_stack;
|
||
|
|
||
|
/* FAULT enable register SHCSR */
|
||
|
#define SHCSR (*(volatile uint32_t *)(0xE000ED24))
|
||
|
|
||
|
/* Bit to enable memory fault handler */
|
||
|
#define MEMFAULT_ENABLE (1 << 16)
|
||
|
|
||
|
/* MPU Registers */
|
||
|
#define MPU_TYPE (*(volatile uint32_t *)(MPU_BASE + 0x00))
|
||
|
#define MPU_CTRL (*(volatile uint32_t *)(MPU_BASE + 0x04))
|
||
|
#define MPU_RNR (*(volatile uint32_t *)(MPU_BASE + 0x08))
|
||
|
#define MPU_RBAR (*(volatile uint32_t *)(MPU_BASE + 0x0c))
|
||
|
#define MPU_RASR (*(volatile uint32_t *)(MPU_BASE + 0x10))
|
||
|
|
||
|
/* Some use-case specific values for RASR */
|
||
|
#define RASR_ENABLED (1)
|
||
|
#define RASR_RW (1 << 24)
|
||
|
#define RASR_RDONLY (5 << 24)
|
||
|
#define RASR_NOACCESS (0 << 24)
|
||
|
#define RASR_SCB (7 << 16)
|
||
|
#define RASR_SB (5 << 16)
|
||
|
#define RASR_NOEXEC (1 << 28)
|
||
|
|
||
|
|
||
|
/* Size */
|
||
|
#define MPUSIZE_1K (0x09 << 1)
|
||
|
#define MPUSIZE_2K (0x0a << 1)
|
||
|
#define MPUSIZE_4K (0x0b << 1)
|
||
|
#define MPUSIZE_8K (0x0c << 1)
|
||
|
#define MPUSIZE_16K (0x0d << 1)
|
||
|
#define MPUSIZE_32K (0x0e << 1)
|
||
|
#define MPUSIZE_64K (0x0f << 1)
|
||
|
#define MPUSIZE_128K (0x10 << 1)
|
||
|
#define MPUSIZE_256K (0x11 << 1)
|
||
|
#define MPUSIZE_512K (0x12 << 1)
|
||
|
#define MPUSIZE_1M (0x13 << 1)
|
||
|
#define MPUSIZE_2M (0x14 << 1)
|
||
|
#define MPUSIZE_4M (0x15 << 1)
|
||
|
#define MPUSIZE_8M (0x16 << 1)
|
||
|
#define MPUSIZE_16M (0x17 << 1)
|
||
|
#define MPUSIZE_32M (0x18 << 1)
|
||
|
#define MPUSIZE_64M (0x19 << 1)
|
||
|
#define MPUSIZE_128M (0x1a << 1)
|
||
|
#define MPUSIZE_256M (0x1b << 1)
|
||
|
#define MPUSIZE_512M (0x1c << 1)
|
||
|
#define MPUSIZE_1G (0x1d << 1)
|
||
|
#define MPUSIZE_2G (0x1e << 1)
|
||
|
#define MPUSIZE_4G (0x1f << 1)
|
||
|
|
||
|
|
||
|
#define STACK_SIZE (4 * 1024)
|
||
|
|
||
|
static void mpu_set_region(int region, uint32_t start, uint32_t attr)
|
||
|
{
|
||
|
MPU_RNR = region;
|
||
|
MPU_RBAR = start;
|
||
|
MPU_RNR = region;
|
||
|
MPU_RASR = attr;
|
||
|
}
|
||
|
|
||
|
|
||
|
int f7_mpu_enable(void)
|
||
|
{
|
||
|
volatile uint32_t type;
|
||
|
volatile uint32_t start;
|
||
|
volatile uint32_t attr;
|
||
|
|
||
|
type = MPU_TYPE;
|
||
|
if (type == 0) {
|
||
|
/* MPU not present! */
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Disable MPU to reconfigure regions */
|
||
|
MPU_CTRL = 0;
|
||
|
|
||
|
/* Set flash area as read-only, executable */
|
||
|
start = 0;
|
||
|
attr = RASR_ENABLED | MPUSIZE_4G | RASR_SCB | RASR_RW;
|
||
|
mpu_set_region(0, start, attr);
|
||
|
|
||
|
/* Enable the MPU, no background region */
|
||
|
MPU_CTRL = 1;
|
||
|
return 0;
|
||
|
|
||
|
}
|