aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/device/nxp/mimxrt1062_mpu.go
blob: e5dbfb750214aa2e245c53f29eb2c735ecbf7b22 (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// Hand created file. DO NOT DELETE.
// Type definitions, fields, and constants associated with the MPU peripheral
// of the NXP MIMXRT1062.

//go:build nxp && mimxrt1062

package nxp

import (
	"device/arm"
	"runtime/volatile"
	"unsafe"
)

type MPU_Type struct {
	TYPE    volatile.Register32 // 0x000 (R/ ) - MPU Type Register
	CTRL    volatile.Register32 // 0x004 (R/W) - MPU Control Register
	RNR     volatile.Register32 // 0x008 (R/W) - MPU Region RNRber Register
	RBAR    volatile.Register32 // 0x00C (R/W) - MPU Region Base Address Register
	RASR    volatile.Register32 // 0x010 (R/W) - MPU Region Attribute and Size Register
	RBAR_A1 volatile.Register32 // 0x014 (R/W) - MPU Alias 1 Region Base Address Register
	RASR_A1 volatile.Register32 // 0x018 (R/W) - MPU Alias 1 Region Attribute and Size Register
	RBAR_A2 volatile.Register32 // 0x01C (R/W) - MPU Alias 2 Region Base Address Register
	RASR_A2 volatile.Register32 // 0x020 (R/W) - MPU Alias 2 Region Attribute and Size Register
	RBAR_A3 volatile.Register32 // 0x024 (R/W) - MPU Alias 3 Region Base Address Register
	RASR_A3 volatile.Register32 // 0x028 (R/W) - MPU Alias 3 Region Attribute and Size Register
}

var MPU = (*MPU_Type)(unsafe.Pointer(uintptr(0xe000ed90)))

type (
	RegionSize  uint32
	AccessPerms uint32
	Extension   uint32
)

// MPU Control Register Definitions
const (
	MPU_CTRL_PRIVDEFENA_Pos = 2                            // MPU CTRL: PRIVDEFENA Position
	MPU_CTRL_PRIVDEFENA_Msk = 1 << MPU_CTRL_PRIVDEFENA_Pos // MPU CTRL: PRIVDEFENA Mask
	MPU_CTRL_HFNMIENA_Pos   = 1                            // MPU CTRL: HFNMIENA Position
	MPU_CTRL_HFNMIENA_Msk   = 1 << MPU_CTRL_HFNMIENA_Pos   // MPU CTRL: HFNMIENA Mask
	MPU_CTRL_ENABLE_Pos     = 0                            // MPU CTRL: ENABLE Position
	MPU_CTRL_ENABLE_Msk     = 1                            // MPU CTRL: ENABLE Mask
)

// MPU Region Base Address Register Definitions
const (
	MPU_RBAR_ADDR_Pos   = 5                              // MPU RBAR: ADDR Position
	MPU_RBAR_ADDR_Msk   = 0x7FFFFFF << MPU_RBAR_ADDR_Pos // MPU RBAR: ADDR Mask
	MPU_RBAR_VALID_Pos  = 4                              // MPU RBAR: VALID Position
	MPU_RBAR_VALID_Msk  = 1 << MPU_RBAR_VALID_Pos        // MPU RBAR: VALID Mask
	MPU_RBAR_REGION_Pos = 0                              // MPU RBAR: REGION Position
	MPU_RBAR_REGION_Msk = 0xF                            // MPU RBAR: REGION Mask
)

// MPU Region Attribute and Size Register Definitions
const (
	MPU_RASR_ATTRS_Pos  = 16                           // MPU RASR: MPU Region Attribute field Position
	MPU_RASR_ATTRS_Msk  = 0xFFFF << MPU_RASR_ATTRS_Pos // MPU RASR: MPU Region Attribute field Mask
	MPU_RASR_XN_Pos     = 28                           // MPU RASR: ATTRS.XN Position
	MPU_RASR_XN_Msk     = 1 << MPU_RASR_XN_Pos         // MPU RASR: ATTRS.XN Mask
	MPU_RASR_AP_Pos     = 24                           // MPU RASR: ATTRS.AP Position
	MPU_RASR_AP_Msk     = 0x7 << MPU_RASR_AP_Pos       // MPU RASR: ATTRS.AP Mask
	MPU_RASR_TEX_Pos    = 19                           // MPU RASR: ATTRS.TEX Position
	MPU_RASR_TEX_Msk    = 0x7 << MPU_RASR_TEX_Pos      // MPU RASR: ATTRS.TEX Mask
	MPU_RASR_S_Pos      = 18                           // MPU RASR: ATTRS.S Position
	MPU_RASR_S_Msk      = 1 << MPU_RASR_S_Pos          // MPU RASR: ATTRS.S Mask
	MPU_RASR_C_Pos      = 17                           // MPU RASR: ATTRS.C Position
	MPU_RASR_C_Msk      = 1 << MPU_RASR_C_Pos          // MPU RASR: ATTRS.C Mask
	MPU_RASR_B_Pos      = 16                           // MPU RASR: ATTRS.B Position
	MPU_RASR_B_Msk      = 1 << MPU_RASR_B_Pos          // MPU RASR: ATTRS.B Mask
	MPU_RASR_SRD_Pos    = 8                            // MPU RASR: Sub-Region Disable Position
	MPU_RASR_SRD_Msk    = 0xFF << MPU_RASR_SRD_Pos     // MPU RASR: Sub-Region Disable Mask
	MPU_RASR_SIZE_Pos   = 1                            // MPU RASR: Region Size Field Position
	MPU_RASR_SIZE_Msk   = 0x1F << MPU_RASR_SIZE_Pos    // MPU RASR: Region Size Field Mask
	MPU_RASR_ENABLE_Pos = 0                            // MPU RASR: Region enable bit Position
	MPU_RASR_ENABLE_Msk = 1                            // MPU RASR: Region enable bit Disable Mask
)

const (
	SCB_DCISW_WAY_Pos = 30                         // SCB DCISW: Way Position
	SCB_DCISW_WAY_Msk = 3 << SCB_DCISW_WAY_Pos     // SCB DCISW: Way Mask
	SCB_DCISW_SET_Pos = 5                          // SCB DCISW: Set Position
	SCB_DCISW_SET_Msk = 0x1FF << SCB_DCISW_SET_Pos // SCB DCISW: Set Mask
)

const (
	SCB_DCCISW_WAY_Pos = 30                          // SCB DCCISW: Way Position
	SCB_DCCISW_WAY_Msk = 3 << SCB_DCCISW_WAY_Pos     // SCB DCCISW: Way Mask
	SCB_DCCISW_SET_Pos = 5                           // SCB DCCISW: Set Position
	SCB_DCCISW_SET_Msk = 0x1FF << SCB_DCCISW_SET_Pos // SCB DCCISW: Set Mask
)

const (
	RGNSZ_32B   RegionSize = 0x04 // MPU Region Size 32 Bytes
	RGNSZ_64B   RegionSize = 0x05 // MPU Region Size 64 Bytes
	RGNSZ_128B  RegionSize = 0x06 // MPU Region Size 128 Bytes
	RGNSZ_256B  RegionSize = 0x07 // MPU Region Size 256 Bytes
	RGNSZ_512B  RegionSize = 0x08 // MPU Region Size 512 Bytes
	RGNSZ_1KB   RegionSize = 0x09 // MPU Region Size 1 KByte
	RGNSZ_2KB   RegionSize = 0x0A // MPU Region Size 2 KBytes
	RGNSZ_4KB   RegionSize = 0x0B // MPU Region Size 4 KBytes
	RGNSZ_8KB   RegionSize = 0x0C // MPU Region Size 8 KBytes
	RGNSZ_16KB  RegionSize = 0x0D // MPU Region Size 16 KBytes
	RGNSZ_32KB  RegionSize = 0x0E // MPU Region Size 32 KBytes
	RGNSZ_64KB  RegionSize = 0x0F // MPU Region Size 64 KBytes
	RGNSZ_128KB RegionSize = 0x10 // MPU Region Size 128 KBytes
	RGNSZ_256KB RegionSize = 0x11 // MPU Region Size 256 KBytes
	RGNSZ_512KB RegionSize = 0x12 // MPU Region Size 512 KBytes
	RGNSZ_1MB   RegionSize = 0x13 // MPU Region Size 1 MByte
	RGNSZ_2MB   RegionSize = 0x14 // MPU Region Size 2 MBytes
	RGNSZ_4MB   RegionSize = 0x15 // MPU Region Size 4 MBytes
	RGNSZ_8MB   RegionSize = 0x16 // MPU Region Size 8 MBytes
	RGNSZ_16MB  RegionSize = 0x17 // MPU Region Size 16 MBytes
	RGNSZ_32MB  RegionSize = 0x18 // MPU Region Size 32 MBytes
	RGNSZ_64MB  RegionSize = 0x19 // MPU Region Size 64 MBytes
	RGNSZ_128MB RegionSize = 0x1A // MPU Region Size 128 MBytes
	RGNSZ_256MB RegionSize = 0x1B // MPU Region Size 256 MBytes
	RGNSZ_512MB RegionSize = 0x1C // MPU Region Size 512 MBytes
	RGNSZ_1GB   RegionSize = 0x1D // MPU Region Size 1 GByte
	RGNSZ_2GB   RegionSize = 0x1E // MPU Region Size 2 GBytes
	RGNSZ_4GB   RegionSize = 0x1F // MPU Region Size 4 GBytes
)

const (
	PERM_NONE AccessPerms = 0 // MPU Access Permission no access
	PERM_PRIV AccessPerms = 1 // MPU Access Permission privileged access only
	PERM_URO  AccessPerms = 2 // MPU Access Permission unprivileged access read-only
	PERM_FULL AccessPerms = 3 // MPU Access Permission full access
	PERM_PRO  AccessPerms = 5 // MPU Access Permission privileged access read-only
	PERM_RO   AccessPerms = 6 // MPU Access Permission read-only access
)

const (
	EXTN_NORMAL Extension = 0
	EXTN_DEVICE Extension = 2
)

func (mpu *MPU_Type) Enable(enable bool) {
	if enable {
		mpu.CTRL.Set(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk)
		SystemControl.SHCSR.SetBits(SCB_SHCSR_MEMFAULTENA_Msk)
		arm.Asm("dsb 0xF")
		arm.Asm("isb 0xF")
		enableDcache(true)
		enableIcache(true)
	} else {
		enableIcache(false)
		enableDcache(false)
		arm.Asm("dmb 0xF")
		SystemControl.SHCSR.ClearBits(SCB_SHCSR_MEMFAULTENA_Msk)
		mpu.CTRL.ClearBits(MPU_CTRL_ENABLE_Msk)
	}
}

// MPU Region Base Address Register value
func (mpu *MPU_Type) SetRBAR(region uint32, baseAddress uint32) {
	mpu.RBAR.Set((baseAddress & MPU_RBAR_ADDR_Msk) |
		(region & MPU_RBAR_REGION_Msk) | MPU_RBAR_VALID_Msk)
}

// MPU Region Attribute and Size Register value
func (mpu *MPU_Type) SetRASR(size RegionSize, access AccessPerms, ext Extension, exec, share, cache, buffer, disable bool) {
	boolBit := func(b bool) uint32 {
		if b {
			return 1
		}
		return 0
	}
	attr := ((uint32(ext) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) |
		((boolBit(share) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) |
		((boolBit(cache) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) |
		((boolBit(buffer) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)
	mpu.RASR.Set(((boolBit(!exec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) |
		((uint32(access) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) |
		(attr & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk)) |
		((boolBit(disable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) |
		((uint32(size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) |
		MPU_RASR_ENABLE_Msk)
}

func enableIcache(enable bool) {
	if enable != SystemControl.CCR.HasBits(SCB_CCR_IC_Msk) {
		if enable {
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
			SystemControl.ICIALLU.Set(0)
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
			SystemControl.CCR.SetBits(SCB_CCR_IC_Msk)
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
		} else {
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
			SystemControl.CCR.ClearBits(SCB_CCR_IC_Msk)
			SystemControl.ICIALLU.Set(0)
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
		}
	}
}

var (
	dcacheCcsidr volatile.Register32
	dcacheSets   volatile.Register32
	dcacheWays   volatile.Register32
)

func enableDcache(enable bool) {
	if enable != SystemControl.CCR.HasBits(SCB_CCR_DC_Msk) {
		if enable {
			SystemControl.CSSELR.Set(0)
			arm.Asm("dsb 0xF")
			ccsidr := SystemControl.CCSIDR.Get()
			sets := (ccsidr & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos
			for sets != 0 {
				ways := (ccsidr & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos
				for ways != 0 {
					SystemControl.DCISW.Set(
						((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
							((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk))
					ways--
				}
				sets--
			}
			arm.Asm("dsb 0xF")
			SystemControl.CCR.SetBits(SCB_CCR_DC_Msk)
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
		} else {
			SystemControl.CSSELR.Set(0)
			arm.Asm("dsb 0xF")
			SystemControl.CCR.ClearBits(SCB_CCR_DC_Msk)
			arm.Asm("dsb 0xF")
			dcacheCcsidr.Set(SystemControl.CCSIDR.Get())
			dcacheSets.Set((dcacheCcsidr.Get() & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos)
			for dcacheSets.Get() != 0 {
				dcacheWays.Set((dcacheCcsidr.Get() & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
				for dcacheWays.Get() != 0 {
					SystemControl.DCCISW.Set(
						((dcacheSets.Get() << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
							((dcacheWays.Get() << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk))
					dcacheWays.Set(dcacheWays.Get() - 1)
				}
				dcacheSets.Set(dcacheSets.Get() - 1)
			}
			arm.Asm("dsb 0xF")
			arm.Asm("isb 0xF")
		}
	}
}