-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tzc380 driver support. The usage: Use tzc_init(vaddr_t base) to get the tzc380 configuration. Use tzc_configure_region to configure the memory region, such as "tzc_configure_region(5, 0x4e000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_32M) | TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_S_RW);" Signed-off-by: Peng Fan <peng.fan@nxp.com>
- Loading branch information
Showing
3 changed files
with
391 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/* | ||
* Copyright 2017 NXP | ||
* All rights reserved. | ||
* | ||
* Peng Fan <peng.fan@nxp.com> | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright notice, | ||
* this list of conditions and the following disclaimer in the documentation | ||
* and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <drivers/tzc380.h> | ||
#include <io.h> | ||
#include <kernel/panic.h> | ||
#include <stddef.h> | ||
#include <trace.h> | ||
#include <util.h> | ||
|
||
/* | ||
* Implementation defined values used to validate inputs later. | ||
* Filters : max of 4 ; 0 to 3 | ||
* Regions : max of 9 ; 0 to 8 | ||
* Address width : Values between 32 to 64 | ||
*/ | ||
struct tzc_instance { | ||
vaddr_t base; | ||
uint8_t addr_width; | ||
uint8_t num_regions; | ||
}; | ||
|
||
static struct tzc_instance tzc; | ||
|
||
static uint32_t tzc_read_build_config(vaddr_t base) | ||
{ | ||
return read32(base + BUILD_CONFIG_OFF); | ||
} | ||
|
||
static void tzc_write_action(vaddr_t base, enum tzc_action action) | ||
{ | ||
write32(action, base + ACTION_OFF); | ||
} | ||
|
||
static void tzc_write_region_base_low(vaddr_t base, uint32_t region, | ||
uint32_t val) | ||
{ | ||
write32(val, base + REGION_SETUP_LOW_OFF(region)); | ||
} | ||
|
||
static void tzc_write_region_base_high(vaddr_t base, uint32_t region, | ||
uint32_t val) | ||
{ | ||
write32(val, base + REGION_SETUP_HIGH_OFF(region)); | ||
} | ||
|
||
static void tzc_write_region_attributes(vaddr_t base, uint32_t region, | ||
uint32_t val) | ||
{ | ||
write32(val, base + REGION_ATTRIBUTES_OFF(region)); | ||
} | ||
|
||
void tzc_init(vaddr_t base) | ||
{ | ||
uint32_t tzc_build; | ||
|
||
assert(base); | ||
tzc.base = base; | ||
|
||
/* Save values we will use later. */ | ||
tzc_build = tzc_read_build_config(tzc.base); | ||
tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & | ||
BUILD_CONFIG_AW_MASK) + 1; | ||
tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & | ||
BUILD_CONFIG_NR_MASK) + 1; | ||
} | ||
|
||
static uint32_t addr_low(vaddr_t addr) | ||
{ | ||
return (uint32_t)addr; | ||
} | ||
|
||
static uint32_t addr_high(vaddr_t addr __unused) | ||
{ | ||
#if (UINTPTR_MAX == UINT64_MAX) | ||
return (addr >> 32); | ||
#else | ||
return 0; | ||
#endif | ||
} | ||
|
||
|
||
/* | ||
* `tzc_configure_region` is used to program regions into the TrustZone | ||
* controller. | ||
*/ | ||
void tzc_configure_region(uint8_t region, vaddr_t region_base, uint32_t attr) | ||
{ | ||
assert(tzc.base); | ||
|
||
assert(region < tzc.num_regions); | ||
|
||
tzc_write_region_base_low(tzc.base, region, addr_low(region_base)); | ||
tzc_write_region_base_high(tzc.base, region, addr_high(region_base)); | ||
tzc_write_region_attributes(tzc.base, region, attr); | ||
} | ||
|
||
void tzc_set_action(enum tzc_action action) | ||
{ | ||
assert(tzc.base); | ||
|
||
/* | ||
* - Currently no handler is provided to trap an error via interrupt | ||
* or exception. | ||
* - The interrupt action has not been tested. | ||
*/ | ||
tzc_write_action(tzc.base, action); | ||
} | ||
|
||
#if TRACE_LEVEL >= TRACE_DEBUG | ||
|
||
static uint32_t tzc_read_region_attributes(vaddr_t base, uint32_t region) | ||
{ | ||
return read32(base + REGION_ATTRIBUTES_OFF(region)); | ||
} | ||
|
||
static uint32_t tzc_read_region_base_low(vaddr_t base, uint32_t region) | ||
{ | ||
return read32(base + REGION_SETUP_LOW_OFF(region)); | ||
} | ||
|
||
static uint32_t tzc_read_region_base_high(vaddr_t base, uint32_t region) | ||
{ | ||
return read32(base + REGION_SETUP_HIGH_OFF(region)); | ||
} | ||
|
||
#define REGION_MAX 16 | ||
void tzc_dump_state(void) | ||
{ | ||
uint32_t n; | ||
uint32_t temp_32reg, temp_32reg_h; | ||
|
||
DMSG("enter"); | ||
DMSG("security_inversion_en %x\n", | ||
read32(tzc.base + SECURITY_INV_EN_OFF)); | ||
for (n = 0; n <= REGION_MAX; n++) { | ||
temp_32reg = tzc_read_region_attributes(tzc.base, n); | ||
if (!(temp_32reg & TZC_ATTR_REGION_EN_MASK)) | ||
continue; | ||
|
||
DMSG("\n"); | ||
DMSG("region %d", n); | ||
temp_32reg = tzc_read_region_base_low(tzc.base, n); | ||
temp_32reg_h = tzc_read_region_base_high(tzc.base, n); | ||
DMSG("region_base: 0x%08x%08x", temp_32reg_h, temp_32reg); | ||
temp_32reg = tzc_read_region_attributes(tzc.base, n); | ||
DMSG("region sp: %x", temp_32reg >> TZC_ATTR_SP_SHIFT); | ||
DMSG("region size: %x\n", (temp_32reg & TZC_REGION_SIZE_MASK) >> TZC_REGION_SIZE_SHIFT); | ||
} | ||
DMSG("exit"); | ||
} | ||
|
||
#endif /* CFG_TRACE_LEVEL >= TRACE_DEBUG */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
/* | ||
* Copyright 2017 NXP | ||
* All rights reserved. | ||
* | ||
* Peng Fan <peng.fan@nxp.com> | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright notice, | ||
* this list of conditions and the following disclaimer in the documentation | ||
* and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#ifndef __DRIVERS_TZC380_H | ||
#define __DRIVERS_TZC380_H | ||
|
||
#include <stdint.h> | ||
#include <types_ext.h> | ||
#include <trace_levels.h> | ||
|
||
#define TZC400_REG_SIZE 0x1000 | ||
|
||
#define BUILD_CONFIG_OFF 0x000 | ||
#define ACTION_OFF 0x004 | ||
#define LOCKDOWN_RANGE_OFF 0x008 | ||
#define LOCKDOWN_SELECT_OFF 0x00C | ||
#define INT_STATUS 0x010 | ||
#define INT_CLEAR 0x014 | ||
|
||
#define FAIL_ADDRESS_LOW_OFF 0x020 | ||
#define FAIL_ADDRESS_HIGH_OFF 0x024 | ||
#define FAIL_CONTROL_OFF 0x028 | ||
#define FAIL_ID 0x02c | ||
|
||
#define SPECULATION_CTRL_OFF 0x030 | ||
#define SECURITY_INV_EN_OFF 0x034 | ||
|
||
#define REGION_SETUP_LOW_OFF(n) (0x100 + n * 0x10) | ||
#define REGION_SETUP_HIGH_OFF(n) (0x104 + n * 0x10) | ||
#define REGION_ATTRIBUTES_OFF(n) (0x108 + n * 0x10) | ||
|
||
/* ID Registers */ | ||
#define PID0_OFF 0xfe0 | ||
#define PID1_OFF 0xfe4 | ||
#define PID2_OFF 0xfe8 | ||
#define PID3_OFF 0xfec | ||
#define PID4_OFF 0xfd0 | ||
#define CID0_OFF 0xff0 | ||
#define CID1_OFF 0xff4 | ||
#define CID2_OFF 0xff8 | ||
#define CID3_OFF 0xffc | ||
|
||
#define BUILD_CONFIG_AW_SHIFT 8 | ||
#define BUILD_CONFIG_AW_MASK 0x3f | ||
#define BUILD_CONFIG_NR_SHIFT 0 | ||
#define BUILD_CONFIG_NR_MASK 0xf | ||
|
||
#define ACTION_RV_SHIFT 0 | ||
#define ACTION_RV_MASK 0x3 | ||
#define ACTION_RV_LOWOK 0x0 | ||
#define ACTION_RV_LOWERR 0x1 | ||
#define ACTION_RV_HIGHOK 0x2 | ||
#define ACTION_RV_HIGHERR 0x3 | ||
|
||
/* Speculation is enabled by default. */ | ||
#define SPECULATION_CTRL_WRITE_DISABLE (1 << 1) | ||
#define SPECULATION_CTRL_READ_DISABLE (1 << 0) | ||
|
||
#define INT_STATUS_OVERRUN_SHIFT 1 | ||
#define INT_STATUS_OVERRUN_MASK 0x1 | ||
#define INT_STATUS_STATUS_SHIFT 0 | ||
#define INT_STATUS_STATUS_MASK 0x1 | ||
|
||
#define INT_CLEAR_CLEAR_SHIFT 0 | ||
#define INT_CLEAR_CLEAR_MASK 0x1 | ||
|
||
#define TZC380_COMPONENT_ID 0xb105f00d | ||
#define TZC380_PERIPH_ID_LOW 0x001bb380 | ||
#define TZC380_PERIPH_ID_HIGH 0x00000004 | ||
|
||
/******************************************************************************* | ||
* Function & variable prototypes | ||
******************************************************************************/ | ||
|
||
/* | ||
* What type of action is expected when an access violation occurs. | ||
* The memory requested is zeroed. But we can also raise and event to | ||
* let the system know it happened. | ||
* We can raise an interrupt(INT) and/or cause an exception(ERR). | ||
* TZC_ACTION_NONE - No interrupt, no Exception | ||
* TZC_ACTION_ERR - No interrupt, raise exception -> sync external | ||
* data abort | ||
* TZC_ACTION_INT - Raise interrupt, no exception | ||
* TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync | ||
* external data abort | ||
*/ | ||
enum tzc_action { | ||
TZC_ACTION_NONE = 0, | ||
TZC_ACTION_ERR = 1, | ||
TZC_ACTION_INT = 2, | ||
TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT) | ||
}; | ||
|
||
|
||
#define TZC_SP_NS_W (1 << 0) | ||
#define TZC_SP_NS_R (1 << 1) | ||
#define TZC_SP_S_W (1 << 2) | ||
#define TZC_SP_S_R (1 << 3) | ||
|
||
#define TZC_ATTR_SP_SHIFT 28 | ||
#define TZC_ATTR_SP_ALL ((TZC_SP_S_W | TZC_SP_S_R | TZC_SP_NS_W | \ | ||
TZC_SP_NS_R) << TZC_ATTR_SP_SHIFT) | ||
#define TZC_ATTR_SP_S_RW ((TZC_SP_S_W | TZC_SP_S_R) << \ | ||
TZC_ATTR_SP_SHIFT) | ||
#define TZC_ATTR_SP_NS_RW ((TZC_SP_NS_W | TZC_SP_NS_R) << \ | ||
TZC_ATTR_SP_SHIFT) | ||
|
||
#define TZC_REGION_SIZE_32K (0xe) | ||
#define TZC_REGION_SIZE_64K (0xf) | ||
#define TZC_REGION_SIZE_128K (0x10) | ||
#define TZC_REGION_SIZE_256K (0x11) | ||
#define TZC_REGION_SIZE_512K (0x12) | ||
#define TZC_REGION_SIZE_1M (0x13) | ||
#define TZC_REGION_SIZE_2M (0x14) | ||
#define TZC_REGION_SIZE_4M (0x15) | ||
#define TZC_REGION_SIZE_8M (0x16) | ||
#define TZC_REGION_SIZE_16M (0x17) | ||
#define TZC_REGION_SIZE_32M (0x18) | ||
#define TZC_REGION_SIZE_64M (0x19) | ||
#define TZC_REGION_SIZE_128M (0x1a) | ||
#define TZC_REGION_SIZE_256M (0x1b) | ||
#define TZC_REGION_SIZE_512M (0x1c) | ||
#define TZC_REGION_SIZE_1G (0x1d) | ||
#define TZC_REGION_SIZE_2G (0x1e) | ||
#define TZC_REGION_SIZE_4G (0x1f) | ||
#define TZC_REGION_SIZE_8G (0x20) | ||
#define TZC_REGION_SIZE_16G (0x21) | ||
#define TZC_REGION_SIZE_32G (0x22) | ||
#define TZC_REGION_SIZE_64G (0x23) | ||
#define TZC_REGION_SIZE_128G (0x24) | ||
#define TZC_REGION_SIZE_256G (0x25) | ||
#define TZC_REGION_SIZE_512G (0x26) | ||
#define TZC_REGION_SIZE_1T (0x27) | ||
#define TZC_REGION_SIZE_2T (0x28) | ||
#define TZC_REGION_SIZE_4T (0x29) | ||
#define TZC_REGION_SIZE_8T (0x2a) | ||
#define TZC_REGION_SIZE_16T (0x2b) | ||
#define TZC_REGION_SIZE_32T (0x2c) | ||
#define TZC_REGION_SIZE_64T (0x2d) | ||
#define TZC_REGION_SIZE_128T (0x2e) | ||
#define TZC_REGION_SIZE_256T (0x2f) | ||
#define TZC_REGION_SIZE_512T (0x30) | ||
#define TZC_REGION_SIZE_1P (0x31) | ||
#define TZC_REGION_SIZE_2P (0x32) | ||
#define TZC_REGION_SIZE_4P (0x33) | ||
#define TZC_REGION_SIZE_8P (0x34) | ||
#define TZC_REGION_SIZE_16P (0x35) | ||
#define TZC_REGION_SIZE_32P (0x36) | ||
#define TZC_REGION_SIZE_64P (0x37) | ||
#define TZC_REGION_SIZE_128P (0x38) | ||
#define TZC_REGION_SIZE_256P (0x39) | ||
#define TZC_REGION_SIZE_512P (0x3a) | ||
#define TZC_REGION_SIZE_1E (0x3b) | ||
#define TZC_REGION_SIZE_2E (0x3c) | ||
#define TZC_REGION_SIZE_4E (0x3d) | ||
#define TZC_REGION_SIZE_8E (0x3e) | ||
#define TZC_REGION_SIZE_16E (0x3f) | ||
|
||
#define TZC_REGION_SIZE_SHIFT (0x1) | ||
#define TZC_REGION_SIZE_MASK (0x3f << 1) | ||
#define TZC_ATTR_REGION_SIZE(s) ((s) << TZC_REGION_SIZE_SHIFT) | ||
|
||
#define TZC_ATTR() | ||
|
||
#define TZC_ATTR_REGION_EN_SHIFT (0x0) | ||
#define TZC_ATTR_REGION_EN_MASK (0x1) | ||
|
||
#define TZC_ATTR_REGION_EN | ||
#define TZC_ATTR_REGION_ENABLE (0x1) | ||
#define TZC_ATTR_REGION_DISABLE (0x0) | ||
|
||
void tzc_init(vaddr_t base); | ||
void tzc_configure_region(uint8_t region, vaddr_t region_base, size_t size); | ||
void tzc_set_action(enum tzc_action action); | ||
|
||
#if TRACE_LEVEL >= TRACE_DEBUG | ||
void tzc_dump_state(void); | ||
#else | ||
static inline void tzc_dump_state(void) | ||
{ | ||
} | ||
#endif | ||
|
||
#endif /* __DRIVERS_TZC400_H */ |