blob: f14dacc0b044b2da073da04345ded89e1af0a208 [file] [log] [blame]
/* $Id: //depot/dev/Foxhill/Xtensa/OS/include/xtensa/mpuasm.h#5 $ */
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _MPUASM_H_
#define _MPUASM_H_
#include <xtensa/config/core.h>
/*
* Macro for writing MPU map.
*
* Parameters:
* a_map => address register containing pointer to MPU map
* a_num_entries => number of entries in the forementioned map
* a_temp1, a_temp2. => address register temporaries
* a_temp3, a_temp4
*/
.macro mpu_write_map a_map, a_num_entries, a_temp1, a_temp2, a_temp3, a_temp4
#if XCHAL_HAVE_MPU
movi \a_temp1, 0
wsr.cacheadrdis \a_temp1 // enable the cache in all regions
wsr.mpuenb \a_temp1 // disable all foreground entries
// Clear out the unused entries.
//
// Currently we are clearing out all the entries because currently
// the entries must be ordered even if they are all disabled.
// If out of order entries were permitted when all are disabled,
// performance could be improved by clearing XCHAL_MPU_ENTRIES - n
// (n = number of entries) rather than XCHAL_MPU_ENTRIES - 1 entries.
//
movi \a_temp2, 0
movi \a_temp3, XCHAL_MPU_ENTRIES - 1
j 1f
.align 16 // this alignment is done to ensure that
1:
memw // todo currently wptlb must be preceeded by a memw. The instructions must
// be aligned to ensure that both are in the same cache line. These statements should be
// properly conditionalized when that restriction is removed from the HW
wptlb \a_temp2, \a_temp1
addi \a_temp2, \a_temp2, 1
bltu \a_temp2, \a_temp3, 1b
// Write the new entries.
//
beqz \a_num_entries, 4f // if no entries, skip loop
addx8 \a_map, \a_num_entries, \a_map // compute end of provided map
j 3f
.align 16
2: memw // todo currently wptlb must be preceeded by a memw. The instructions must
// be aligned to ensure that both are in the same cache line. These statements should be
// properly conditionalized when that restriction is removed from the HW
wptlb \a_temp2, \a_temp4
addi \a_temp3, \a_temp3, -1
beqz \a_num_entries, 4f // loop until done
3: addi \a_map, \a_map, -8
l32i \a_temp2, \a_map, 4 // get at (acc.rights, memtype)
l32i \a_temp4, \a_map, 0 // get as (vstart, valid)
addi \a_num_entries, \a_num_entries, -1
extui \a_temp1, \a_temp2, 0, 5 // entry index portion
xor \a_temp2, \a_temp2, \a_temp1 // zero it
or \a_temp2, \a_temp2, \a_temp3 // set index = \a_temp3
j 2b
4:
#endif
.endm
/*
* Macro for reading MPU map
*
* Parameters:
* a_map_ptr => address register pointing to memory where map is written
* a_temp1, a_temp2 => address register temporaries
*/
.macro mpu_read_map a_map_ptr, a_temp1, a_temp2
#if XCHAL_HAVE_MPU
movi \a_temp1, XCHAL_MPU_ENTRIES // set index to last entry + 1
addx8 \a_map_ptr, \a_temp1, \a_map_ptr // set map ptr to last entry + 1
1: addi \a_temp1, \a_temp1, -1 // decrement index
addi \a_map_ptr, \a_map_ptr, -8 // decrement index
rptlb0 \a_temp2, \a_temp1 // read 1/2 of entry
s32i \a_temp2, \a_map_ptr, 0 // write 1/2 of entry
rptlb1 \a_temp2, \a_temp1
s32i \a_temp2, \a_map_ptr, 4
bnez \a_temp1, 1b // loop until done
#endif
.endm
#endif