1 /* $Id: //depot/dev/Foxhill/Xtensa/OS/include/xtensa/mpuasm.h#5 $ */
2 
3 /*
4  * Copyright (c) 2016 Cadence Design Systems, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef _MPUASM_H_
27 #define _MPUASM_H_
28 #include <xtensa/config/core.h>
29 
30 /*
31  * Macro for writing MPU map.
32  *
33  * Parameters:
34  * 	a_map				=>	address register containing pointer to MPU map
35  * 	a_num_entries		=>	number of entries in the forementioned map
36  * 	a_temp1, a_temp2.	=>  address register temporaries
37  * 	a_temp3, a_temp4
38  */
39 
40 .macro mpu_write_map a_map, a_num_entries, a_temp1, a_temp2, a_temp3, a_temp4
41 #if XCHAL_HAVE_MPU
42 	movi	\a_temp1, 0
43 	wsr.cacheadrdis \a_temp1 // enable the cache in all regions
44 	wsr.mpuenb	\a_temp1	// disable all foreground entries
45 
46     // Clear out the unused entries.
47     //
48     // Currently we are clearing out all the entries because currently
49     // the entries must be ordered even if they are all disabled.
50     // If out of order entries were permitted when all are disabled,
51     // performance could be improved by clearing XCHAL_MPU_ENTRIES - n
52 	// (n = number of entries) rather than XCHAL_MPU_ENTRIES - 1 entries.
53 	//
54 	movi	\a_temp2, 0
55 	movi	\a_temp3, XCHAL_MPU_ENTRIES - 1
56 	j	1f
57 	.align 16 // this alignment is done to ensure that
58 1:
59 	memw     // todo currently wptlb must be preceeded by a memw.  The instructions must
60 	// be aligned to ensure that both are in the same cache line.  These statements should be
61 	// properly conditionalized when that restriction is removed from the HW
62 	wptlb	\a_temp2, \a_temp1
63 	addi	\a_temp2, \a_temp2, 1
64 	bltu	\a_temp2, \a_temp3, 1b
65 
66         // Write the new entries.
67 	//
68 	beqz	\a_num_entries, 4f				// if no entries, skip loop
69 	addx8	\a_map, \a_num_entries, \a_map			// compute end of provided map
70 	j		3f
71 	.align 16
72 2:	memw     // todo currently wptlb must be preceeded by a memw.  The instructions must
73 	// be aligned to ensure that both are in the same cache line.  These statements should be
74 	// properly conditionalized when that restriction is removed from the HW
75 	wptlb	\a_temp2, \a_temp4
76 	addi	\a_temp3, \a_temp3, -1
77 	beqz	\a_num_entries, 4f		// loop until done
78 3:	addi	\a_map, \a_map, -8
79 	l32i	\a_temp2, \a_map, 4			// get at (acc.rights, memtype)
80 	l32i	\a_temp4, \a_map, 0			// get as (vstart, valid)
81 	addi	\a_num_entries, \a_num_entries, -1
82 	extui	\a_temp1, \a_temp2, 0, 5			// entry index portion
83 	xor		\a_temp2, \a_temp2, \a_temp1			// zero it
84 	or		\a_temp2, \a_temp2, \a_temp3			// set index = \a_temp3
85 	j		2b
86 4:
87 #endif
88 .endm
89 
90 /*
91  * Macro for reading MPU map
92  *
93  * Parameters:
94  * 	a_map_ptr			=> address register pointing to memory where map is written
95  * 	a_temp1, a_temp2	=> address register temporaries
96  */
97 .macro mpu_read_map a_map_ptr, a_temp1, a_temp2
98 #if XCHAL_HAVE_MPU
99 	movi	\a_temp1, XCHAL_MPU_ENTRIES // set index to last entry + 1
100 	addx8	\a_map_ptr, \a_temp1, \a_map_ptr // set map ptr to last entry + 1
101 1:	addi	\a_temp1, \a_temp1, -1 // decrement index
102 	addi	\a_map_ptr, \a_map_ptr, -8 // decrement index
103 	rptlb0	\a_temp2, \a_temp1 // read 1/2 of entry
104 	s32i	\a_temp2, \a_map_ptr, 0 // write 1/2 of entry
105 	rptlb1	\a_temp2,	\a_temp1
106 	s32i	\a_temp2, \a_map_ptr, 4
107 	bnez	\a_temp1, 1b // loop until done
108 #endif
109 	.endm
110 
111 #endif
112