summaryrefslogtreecommitdiff
path: root/core/cortex-m/include/mpu.h
blob: 610728b501b2194ce0f66f943b3797540d50e4e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Copyright 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* MPU module for Cortex-M3 */

#ifndef __CROS_EC_MPU_H
#define __CROS_EC_MPU_H

#include "common.h"
#include "config.h" /* chips might override MPU attribute settings */

/*
 * ARMv7-M SRAM region
 */
#define CORTEX_M_SRAM_BASE	0x20000000

/*
 * Region assignment. 7 as the highest, a higher index has a higher priority.
 * For example, using 7 for .iram.text allows us to mark entire RAM XN except
 * .iram.text, which is used for hibernation.
 * Region assignment is currently wasteful and can be changed if more
 * regions are needed in the future. For example, a second region may not
 * be necessary for all types, and REGION_CODE_RAM / REGION_STORAGE can be
 * made mutually exclusive.
 */
enum mpu_region {
	REGION_DATA_RAM = 0,		/* For internal data RAM */
	REGION_DATA_RAM2 = 1,		/* Second region for unaligned size */
	REGION_CODE_RAM = 2,		/* For internal code RAM */
	REGION_CODE_RAM2 = 3,		/* Second region for unaligned size */
	REGION_STORAGE = 4,		/* For mapped internal storage */
	REGION_STORAGE2 = 5,		/* Second region for unaligned size */
	REGION_DATA_RAM_TEXT = 6,	/* Exempt region of data RAM */
	REGION_CHIP_RESERVED = 7,	/* Reserved for use in chip/ */
	/* only for chips with MPU supporting 16 regions */
	REGION_UNCACHED_RAM = 8,        /* For uncached data RAM */
	REGION_UNCACHED_RAM2 = 9,       /* Second region for unaligned size */
	REGION_ROLLBACK = 10,           /* For rollback */
};

#define MPU_TYPE		REG32(0xe000ed90)
#define MPU_CTRL		REG32(0xe000ed94)
#define MPU_NUMBER		REG32(0xe000ed98)
#define MPU_BASE		REG32(0xe000ed9c)
#define MPU_SIZE		REG16(0xe000eda0)
#define MPU_ATTR		REG16(0xe000eda2)

/*
 * See ARM v7-M Architecture Reference Manual
 * Section B3.5.5 MPU Type Register, MPU_TYPE
 */
#define MPU_TYPE_UNIFIED_MASK	0x00FF0001
#define MPU_TYPE_REG_COUNT(t)	(((t) >> 8) & 0xFF)

#define MPU_CTRL_PRIVDEFEN	BIT(2)
#define MPU_CTRL_HFNMIENA	BIT(1)
#define MPU_CTRL_ENABLE		BIT(0)

/*
 * Minimum region size is 32 bytes, 5 bits of address space
 */
#define MPU_SIZE_BITS_MIN	5

/*
 * XN (execute never) bit. It's bit 12 if accessed by halfword.
 *   0: XN off
 *   1: XN on
 */
#define MPU_ATTR_XN		BIT(12)

/* AP bit. See table 3-5 of Stellaris LM4F232H5QC datasheet for details */
#define MPU_ATTR_NO_NO (0 << 8)  /* previleged no access, unprev no access */
#define MPU_ATTR_RW_NO (1 << 8)  /* previleged ReadWrite, unprev no access */
#define MPU_ATTR_RW_RO (2 << 8)  /* previleged ReadWrite, unprev Read-only */
#define MPU_ATTR_RW_RW (3 << 8)  /* previleged ReadWrite, unprev ReadWrite */
#define MPU_ATTR_RO_NO (5 << 8)  /* previleged Read-only, unprev no access */

/* Suggested value for TEX S/C/B bit. See table 3-6 of Stellaris LM4F232H5QC
 * datasheet and table 38 of STM32F10xxx Cortex-M3 programming manual. */
#ifndef MPU_ATTR_INTERNAL_SRAM
#define MPU_ATTR_INTERNAL_SRAM  6  /* for Internal SRAM */
#endif
#ifndef MPU_ATTR_FLASH_MEMORY
#define MPU_ATTR_FLASH_MEMORY   2  /* for flash memory */
#endif

/* Represent RW with at most 2 MPU regions. */
#define MAX_RW_REGIONS 2
struct mpu_rw_regions {
	int num_regions;
	uint32_t addr[MAX_RW_REGIONS];
	uint32_t size[MAX_RW_REGIONS];
};

/**
 * Enable MPU
 */
void mpu_enable(void);

/**
 * Returns the value of MPU type register
 *
 * Bit fields:
 * [15:8] Number of the data regions implemented or 0 if MPU is not present.
 * [1]    0: unified (no distinction between instruction and data)
 *        1: separated
 */
uint32_t mpu_get_type(void);

/* Location of iram.text */
extern char __iram_text_start;
extern char __iram_text_end;

/**
 * Protect RAM from code execution
 */
int mpu_protect_data_ram(void);

/**
 * Protect code RAM from being overwritten
 */
int mpu_protect_code_ram(void);

/**
 * Protect internal mapped flash memory from code execution
 */
int mpu_lock_ro_flash(void);
int mpu_lock_rw_flash(void);

/**
 * Protect/unprotect rollback region readback.
 */
int mpu_lock_rollback(int lock);

/**
 * Initialize MPU.
 * It disables all regions if MPU is implemented. Otherwise, returns
 * EC_ERROR_UNIMPLEMENTED.
 */
int mpu_pre_init(void);

#endif /* __CROS_EC_MPU_H */