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 package ti.sysbios.family.c64p;
39
40 /*!
41 * ======== MemoryProtect ========
42 * MemoryProtect Module
43 *
44 * This module provide an API to {@link #getPA() get} and to
45 * {@link #setPA() set} the permission attributes of a memory range.
46 * A memory range can be set to user {@link #MPPA_UX executable},
47 * user {@link #MPPA_UW writable}, user {@link #MPPA_UR readable},
48 * supervisor {@link #MPPA_SX executable}, supervisor
49 * {@link #MPPA_SW writable}, or supervisor {@link #MPPA_SR readable}.
50 * Setting a memory range to only user readable, writable or executable
51 * should be done with caution because BIOS executes in supervisor mode.
52 * Whenever setting the permission attributes of a memory range,
53 * the {@link #MPPA_LOCAL local} CPU access field must be set, if the
54 * local CPU accesses the memory range. If the local field is not set,
55 * an exception is generated if the CPU tries to access the memory range.
56 *
57 * This module is to be used in correlation with the
58 * {@link ti.sysbios.family.c64p.Exception Exception} module.
59 * When this module is in use, external exceptions are enabled by default.
60 * Any memory protection fault which arises generates an exception.
61 * This exception is processed and decoded by the Exception module.
62 *
63 * An example of setting Local L2 RAM to be supervisor read-only and
64 * CPU accessible:
65 *
66 * @p(code)
67 * UInt32 paMask;
68 * paMask = MemoryProtect_MPPA_LOCAL |
69 * MemoryProtect_MPPA_SR;
70 *
71 * MemoryProtect_setPA((Ptr)0x11800000, 0x40000, paMask);
72 * @p
73 *
74 * @p(html)
75 * <h3> Calling Context </h3>
76 * <table border="1" cellpadding="3">
77 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
78 *
79 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
80 * <!-- -->
81 * <tr><td> {@link #getPA} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
82 * <tr><td> {@link #setPA} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
83 * <tr><td colspan="6"> Definitions: <br />
84 * <ul>
85 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
86 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
87 * <li> <b>Task</b>: API is callable from a Task thread. </li>
88 * <li> <b>Main</b>: API is callable during any of these phases: </li>
89 * <ul>
90 * <li> In your module startup after this module is started (e.g. Mod_Module_startupDone() returns TRUE). </li>
91 * <li> During xdc.runtime.Startup.lastFxns. </li>
92 * <li> During main().</li>
93 * <li> During BIOS.startupFxns.</li>
94 * </ul>
95 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
96 * <ul>
97 * <li> During xdc.runtime.Startup.firstFxns.</li>
98 * <li> In your module startup before this module is started (e.g. Mod_Module_startupDone() returns FALSE).</li>
99 * </ul>
100 * </ul>
101 * </td></tr>
102 *
103 * </table>
104 * @p
105 */
106
107 @ModuleStartup
108 @DirectCall
109 module MemoryProtect
110 {
111
112
113 114 115
116 const UInt32 MPPA_UX = 0x00000001; /*! User mode may execute */
117 const UInt32 MPPA_UW = 0x00000002; /*! User mode may write */
118 const UInt32 MPPA_UR = 0x00000004; /*! User mode may read */
119 const UInt32 MPPA_SX = 0x00000008; /*! Supervisor mode may execute */
120 const UInt32 MPPA_SW = 0x00000010; /*! Supervisor mode may write */
121 const UInt32 MPPA_SR = 0x00000020; /*! Supervisor mode read */
122 const UInt32 MPPA_LOCAL = 0x00000100; /*! Local CPU may access */
123
124 /*!
125 * ======== numXMCRegions ========
126 */
127 const UInt numXMCRegions = 16;
128
129 /*!
130 * ======== RegionSize ========
131 */
132 enum RegionSize {
133 RegionSize_4K = 0x0B,
134 RegionSize_8K = 0x0C,
135 RegionSize_16K = 0x0D,
136 RegionSize_32K = 0x0E,
137 RegionSize_64K = 0x0F,
138 RegionSize_128K = 0x10,
139 RegionSize_256K = 0x11,
140 RegionSize_512K = 0x12,
141 RegionSize_1M = 0x13,
142 RegionSize_2M = 0x14,
143 RegionSize_4M = 0x15,
144 RegionSize_8M = 0x16,
145 RegionSize_16M = 0x17,
146 RegionSize_32M = 0x18,
147 RegionSize_64M = 0x19,
148 RegionSize_128M = 0x1A,
149 RegionSize_256M = 0x1B,
150 RegionSize_512M = 0x1C,
151 RegionSize_1G = 0x1D,
152 RegionSize_2G = 0x1E,
153 RegionSize_4G = 0x1F
154 };
155
156 /*!
157 * ======== setXMCRegion ========
158 * Set XMC region mapping and permission attributes
159 *
160 * The C66 CorePac XMC (eXtended Memory Controller) controls access to
161 * L2 SRAM. It contains 16 MPAX registers that define memory translations
162 * and address extensions along with their associated permission
163 * attributes. Regions can overlap one another, with higher numbered
164 * regions taking priority over lower ones. Regions 0 & 1 are
165 * automatically populated by XMC with power up configuratoin values
166 * which map the entire 4GB logical address space to the corresponding
167 * physical address space. These region mappings allow safe fallback
168 * handling for addresses that are not otherwise mapped in higher MPAX
169 * registers.
170 *
171 * Addresses < 0x0C000000 do not reach the XMC, so baseAddr should be
172 * greater than or equal to 0x0C000000.
173 *
174 * @param(regionId) XMC region (segment) number
175 * @param(baseAddr) XMC region logical address
176 * @param(size) XMC region size
177 * @param(rAddr35_12) XMC region translated/extended address bits 35:12
178 * @param(paMask) XMC region permission bits
179 *
180 * @b(returns) if baseAddr < 0x0C000000 or regionId >= numXMCRegions
181 * then FALSE, othersize TRUE and the region is mapped with
182 * permission attributes paMask.
183 */
184 Bool setXMCRegion(Int8 id, Ptr baseAddr, RegionSize size, Ptr rAddr35_12,
185 UInt32 paMask);
186
187 /*!
188 * ======== getPA ========
189 * Gets the PA (Permission Attribute) corresponding to addr.
190 *
191 * @param(addr) address of memory location for which the PA applies
192 * @param(paMask) ptr to location where PA mask for addr is stored
193 *
194 * @b(returns) if address doesn't belong to any configured MPC then
195 * FALSE, otherwise TRUE and *paMask contains addr's
196 * MPPA setting
197 */
198 Bool getPA(Ptr addr, UInt32 *paMask);
199
200 /*!
201 * ======== setPA ========
202 * Sets the PA (Permission Attribute) corresponding to addr/size.
203 *
204 * The PA is applied to all addresses that are spanned by the
205 * memory block.
206 *
207 * @param(addr) begin address of memory block for which the PA applies
208 * @param(size) size of memory block
209 * @param(paMask) PA mask to assign for the memory block
210 *
211 * @b(returns) if address doesn't belong to any configured MPC then
212 * FALSE, otherwise TRUE and PA was written to addr's
213 * MPPA register
214 */
215 Bool setPA(Ptr addr, SizeT size, UInt32 paMask);
216
217 /*!@_nodoc
218 * ======== getPageSize ========
219 * Gets the page size corresponding to addr.
220 *
221 * @param(addr) address of memory location for which the PA applies
222 * @param(pageSize) pointer to location where the page size is stored
223 *
224 * @b(returns) FALSE - address doesn't belong to any configured MPC
225 * TRUE - *pageSize contains addr's MPC page size
226 */
227 Bool getPageSize(Ptr addr, UInt *pageSize);
228
229 /*!@_nodoc
230 * ======== getPrivMode ========
231 * Retrieves the current privilege mode
232 *
233 * @b(returns) current privilege mode
234 */
235 UInt getPrivMode();
236
237 /*!@_nodoc
238 * ======== setPrivMode ========
239 * Sets the privilege mode
240 *
241 * @param(mode) the privilege mode to set
242 */
243 Void setPrivMode(UInt mode);
244
245
246 internal:
247
248 /*!
249 * Struct defining the bit range of an address
250 */
251 struct BitRange {
252 Char msb;
253 Char lsb;
254 };
255
256 /*!
257 * Each MPC needs to implement MPLCK.
258 * DMC/PMC/UMA all conform to the struct below.
259 */
260 struct Lock {
261 volatile UInt32 mpLk0;
262 volatile UInt32 mpLk1;
263 volatile UInt32 mpLk2;
264 volatile UInt32 mpLk3;
265 volatile UInt32 mpLkCmd;
266 volatile UInt32 mpLkStat;
267 };
268
269 /*!
270 * Struct defining the fault registers
271 */
272 struct Fault {
273 volatile UInt32 mpFar;
274 volatile UInt32 mpFsr;
275 volatile UInt32 mpFcr;
276 };
277
278 /*!
279 * Key represents the 128-bit key used for locking
280 * and unlocking a controller's permission attribute entries.
281 * It is used for writing to the MPLK0-MPLK3 registers.
282 */
283 struct Key {
284 UInt32 key0;
285 UInt32 key1;
286 UInt32 key2;
287 UInt32 key3;
288 };
289
290 /*!
291 * Struct defining a controller
292 */
293 struct Controller {
294 Fault *mpFault;
295 Lock *mpLck;
296 UInt32 *mppaTab;
297 UInt32 *mpCfg;
298 UInt32 nPages;
299 UInt32 evtNum;
300 };
301
302 /*!
303 * The following values relate to indexing into the module state
304 * controller array. Subtract 1 from the value before using it as an
305 * index into the 0-based array (NONE isn't used to index the array).
306 */
307 const UInt NONE = 0;
308 const UInt UMAP0 = 1;
309 const UInt UMAP1 = 2;
310 const UInt DMC = 3;
311 const UInt PMC = 4;
312 const UInt UMC = UMAP0;
313
314 /*! lock/unlock values */
315 const UInt LCKUNLOCK = 0x00000001;
316 const UInt LCKLOCK = 0x00000002;
317 const UInt LCKKEYR = 0x00000004;
318 const UInt LKSTATLK = 0x00000001;
319
320 /*! The key values used for locking/unlocking PA table */
321 config Key key = {
322 key0: 0x90abcdef,
323 key1: 0x12345678,
324 key2: 0x87654321,
325 key3: 0xfedcba09
326 };
327
328 /*!
329 * Region Extract Masks table indexed by [controller(0-3)][region(0-1)].
330 * The constants used are fixed based on the GEM architecture spec.
331 * They are based on the minimum theoretical page size (lower constant)
332 * and the number of pages (higher constant minus lower constant).
333 * However, in reality, the actual minimum page size is floored at
334 * some minimum (i.e., the "size" parameter can't, per the
335 * HW design spec, be lower than some minimum (2 for DMC/PMC, 6 for UMC).
336 */
337 config BitRange regExtMasks[4][2];
338
339 /*!
340 * This array is used to map the MegaByte field of an address
341 * (0x00N00000) to the controller that controls that address.
342 * An MPC's address range falls within and is wholy contained
343 * in the MegaByte hex digit.
344 */
345 config Char megaByte2MPC[16];
346
347 /*!
348 * Array of addresses that mark the begin of region 0 for each MPC.
349 * Each MPC contains two regions (0 & 1), however, the first two
350 * entries correspond to the two "regions" of UMC (UMC_P0 & UMC_P1),
351 * and as such the entries for them are forced to the max address
352 * value such that any compare that uses them will be < them,
353 * thus indicating region 0.
354 */
355 config UInt regionCompare[4];
356
357 /*!
358 * Array of addresses that mark the end of region 0 for each MPC.
359 */
360 config UInt regionEnd[4];
361
362 /*! L1 program memory controller */
363 config Controller pmcCtrl;
364
365 /*! L1 data memory controller */
366 config Controller dmcCtrl;
367
368 /*! L2 unified memory controller */
369 config Controller umcCtrl;
370
371 /*!
372 * ======== decodeRegion ========
373 * Determine the beginning and end page numbers for region.
374 *
375 * Validate begAddr/endAddr range to be within internal address space.
376 * Return region (UMAP0/UMAP1/DMC/PMC), beginning and ending page
377 * numbers if valid. Returns -1 if complete address range is not valid.
378 */
379 Int decodeRegion(UInt32 begAddr, UInt32 endAddr,
380 UInt32 *begPage, UInt32 *endPage);
381
382 /*!
383 * ======== getAddrPageSize ========
384 * Returns the page size corresponding to addr.
385 */
386 Int getAddrPageSize(Ptr addr);
387
388 /*!
389 * ======== lock ========
390 * Locks the permission attribute.
391 *
392 * Locks the permission attribute table entries for the
393 * specified controller, using the specified key.
394 */
395 Void lock(Controller *ctrl, Key *key);
396
397 /*!
398 * ======== makeLocal ========
399 * Convert address into a local address
400 *
401 * Validate addr to be a GEM internal address & convert addr into
402 * its local address if global. Returns TRUE if addr is a valid GEM
403 * internal address, and fills space with local/global code (1/0).
404 * Returns FALSE if addr is not a valid GEM internal address. space
405 * is valid only when TRUE is returned.
406 */
407 Bool makeLocal(UInt *addr, UInt *space);
408
409 /*!
410 * ======== readPA ========
411 * Reads the permission attribute
412 *
413 * Returns the permission attribute for the specified
414 * page within the specified controller.
415 */
416 UInt32 readPA(Controller *ctrl, UInt page);
417
418 /*!
419 * ======== unlock ========
420 * Unlocks the permission attribute.
421 *
422 * Unlocks the permission attribute table entries for the
423 * specified controller, using the specified key.
424 */
425 Void unlock(Controller *ctrl, Key *key);
426
427 /*!
428 * ======== writePA ========
429 * Writes the permission attribute
430 *
431 * Writes the permission attribute perm for the specified
432 * page within the specified controller. The permission attribute
433 * entries need to be unlocked first and then locked afterwards.
434 */
435 Void writePA(Controller *ctrl, UInt page, UInt32 perm);
436
437
438 struct Module_State {
439 Controller *controllers[];
440 }
441 }