Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plat-marvell: Add initial support for ARMADA3700 #1946

Merged
merged 1 commit into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .shippable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ build:
- _make PLATFORM=rockchip-rk322x
- _make PLATFORM=rockchip-rk322x CFG_TEE_CORE_LOG_LEVEL=4 DEBUG=1
- _make PLATFORM=sam
- _make PLATFORM=marvell-armada7k8k CFG_ARM64_core=y
- _make PLATFORM=marvell-armada7k8k
- _make PLATFORM=marvell-armada3700

#
# Regressions tests (QEMU)
Expand Down
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,10 @@ script:
- $make PLATFORM=sam

# Marvell ARMADA 7K 8K
- $make PLATFORM=marvell-armada7k8k CFG_ARM64_core=y
- $make PLATFORM=marvell-armada7k8k

# Marvell ARMADA 3700
- $make PLATFORM=marvell-armada3700

# Run regression tests (xtest in QEMU)
- (cd ${HOME}/optee_repo/build && $make check CROSS_COMPILE="ccache arm-linux-gnueabihf-" AARCH32_CROSS_COMPILE=arm-linux-gnueabihf- CFG_TEE_CORE_DEBUG=y DUMP_LOGS_ON_ERROR=1)
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ for these platforms.
| HiSilicon D02 |`Linaro <[email protected]>`|
| Marvell Armada 70x0 |`Kevin Peng <[email protected]>`|
| Marvell Armada 80x0 |`Kevin Peng <[email protected]>`|
| Marvell Armada 3700 |`Kevin Peng <[email protected]>`|
| MediaTek MT8173 EVB Board |`Linaro <[email protected]>`|
| QEMU |`Linaro <[email protected]>`|
| Raspberry Pi3 |`Linaro <[email protected]>`|
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ platforms have different sub-maintainers, please refer to the file
| [HiSilicon D02](http://open-estuary.org/d02-2)|`PLATFORM=d02`| No |
| [HiKey Board (HiSilicon Kirin 620)](https://www.96boards.org/product/hikey)|`PLATFORM=hikey` or `PLATFORM=hikey-hikey`| Yes |
| [HiKey960 Board (HiSilicon Kirin 960)](https://www.96boards.org/product/hikey960)|`PLATFORM=hikey-hikey960`| Yes |
| [Marvell ARMADA 7K Family](http://www.marvell.com/embedded-processors/armada-70xx/)|`PLATFORM=marvell-armada7k8k`| No |
| [Marvell ARMADA 8K Family](http://www.marvell.com/embedded-processors/armada-80xx/)|`PLATFORM=marvell-armada7k8k`| No |
| [Marvell ARMADA 7K Family](http://www.marvell.com/embedded-processors/armada-70xx/)|`PLATFORM=marvell-armada7k8k`| Yes |
| [Marvell ARMADA 8K Family](http://www.marvell.com/embedded-processors/armada-80xx/)|`PLATFORM=marvell-armada7k8k`| Yes |
| [Marvell ARMADA 3700 Family](http://www.marvell.com/embedded-processors/armada-3700/)|`PLATFORM=marvell-armada3700`| Yes |
| [MediaTek MT8173 EVB Board](https://www.mediatek.com/products/tablets/mt8173)|`PLATFORM=mediatek-mt8173`| No |
| [QEMU](http://wiki.qemu.org/Main_Page) |`PLATFORM=vexpress-qemu_virt`| Yes |
| [QEMUv8](http://wiki.qemu.org/Main_Page) |`PLATFORM=vexpress-qemu_armv8a`| Yes |
Expand Down
264 changes: 264 additions & 0 deletions core/arch/arm/plat-marvell/armada3700/hal_sec_perf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/*
* Copyright (C) 2017 Marvell International Ltd.
* All rights reserved.
*
* 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 <initcall.h>
#include <io.h>
#include <kernel/panic.h>
#include <mm/core_memprot.h>
#include <util.h>

#define PHY_2_VIR(addr) ((vaddr_t)phys_to_virt((addr), MEM_AREA_IO_SEC))

#define MCU_BASE 0xD0000000
#define MCU_MC_CONTROL_0_REG PHY_2_VIR(MCU_BASE + 0x044)
#define TRUSTZONE_LOCK BIT(31)

#define MCU_TZ_RANGE_HIGH_REG(x) PHY_2_VIR(MCU_BASE + 0x84 + ((x) << 3))
#define MCU_TZ_RANGE_LOW_REG(x) PHY_2_VIR(MCU_BASE + 0x80 + ((x) << 3))

#define RW_PERM 0x0
#define RO_PERM 0x1
#define WO_PERM 0x2
#define ABORT_PERM 0x3

#define MAX_RANGE_NUM 16
#define INVALID_SIZE_CODE 0xff

#ifdef TEE_RES_CFG_16M
#define RSVD_SEC_MEM (SIZE_8M + SIZE_8M)
#elif defined(TEE_RES_CFG_24M)
#define RSVD_SEC_MEM (SIZE_8M + SIZE_8M + SIZE_8M)
#elif defined(TEE_RES_CFG_8M)
#define RSVD_SEC_MEM SIZE_8M
#else
#error "no reserved secure memory defined."
#endif

#define RA_ADDR TZDRAM_BASE
#define RA_SIZE TZDRAM_SIZE
#define RA_PERM ABORT_PERM

#define TZ_IS_VALID(data) ((data) & (0x1))
#define TZ_SET_VALID(data) ((data) |= (0x1))

#define TZ_GET_PERM(data, ret) ((ret) = (((data) & (0x3 << 1)) >> 1))
#define TZ_SET_PERM(data, val) \
do { \
(data) &= (~(0x3 << 1)); \
(data) |= (((val) & 0x3) << 1); \
} while (0)

#define TZ_GET_RZ_EN(data, ret) ((ret) = (((data) & (0x1 << 3)) >> 3))
#define TZ_SET_RZ_EN(data, val) \
do { \
(data) &= (~(0x1 << 3)); \
(data) |= (((val) & 0x1) << 3); \
} while (0)

#define TZ_GET_AREA_LEN_CODE(data, ret) ((ret) = (((data) & (0x1F << 8)) >> 8))

#define TZ_SET_AREA_LEN_CODE(data, val) \
do { \
(data) &= (~(0x1F << 8)); \
(data) |= (((val) & 0x1F) << 8); \
} while (0)

#define TZ_GET_START_ADDR_L(data, ret) \
((ret) = (((data) & 0xFFF00000)))

#define TZ_SET_START_ADDR_L(data, val) \
do { \
(data) &= (~0xFFF00000); \
(data) |= (((val) & 0xFFF00000)); \
} while (0)

#define TZ_GET_UR_PERM(data, val) ((ret) = (((data) & (0x3 << 4)) >> 4))
#define TZ_SET_UR_PERM(data, val) \
do { \
(data) &= (~(0x3 << 4)); \
(data) |= (((val) & 0x3) << 4); \
} while (0)

#define TZ_GET_UR_RZ_EN(data, val) \
((ret) = (((data) & (0x1 << 6)) >> 6))

#define TZ_SET_UR_RZ_EN(data, val) \
do { \
(data) &= (~(0x1 << 6)); \
(data) |= (((val) & 0x1) << 6); \
} while (0)

/* armada3700 mini region size is 1M */
#define RANGE_SIZE_TO_CODE(size, code, i) \
do { \
(code) = INVALID_SIZE_CODE; \
for ((i) = 0; (i) <= 0x1d; (i)++) { \
if (((uint32_t)0x1 << (i)) == ((size) >> 20)) { \
(code) = (i); \
break; \
} \
} \
} while (0)

#define TZ_LOCK_MC(x) \
do { \
(x) = read32(MCU_MC_CONTROL_0_REG); \
(x) |= (TRUSTZONE_LOCK); \
write32((x), MCU_MC_CONTROL_0_REG); \
} while (0)

#define _IS_ALIGNED(_addr, _algn) (!((_addr) & ((_algn) - 1)))

register_phys_mem(MEM_AREA_IO_SEC, MCU_BASE, CORE_MMU_DEVICE_SIZE);

static int32_t _find_valid_range(void)
{
uint32_t i;
uint32_t tmp;

for (i = 0; i < MAX_RANGE_NUM; i++) {
tmp = read32(MCU_TZ_RANGE_LOW_REG(i));
if (!TZ_IS_VALID(tmp))
return i;
}
return -1;
}

static int32_t set_range(uint32_t addr, uint32_t size, uint32_t perm)
{
uint32_t data;
uint32_t sizecode;
int32_t valid_range;
uint32_t i;

if (!_IS_ALIGNED(addr, SIZE_1M)) {
EMSG("region addr(0x%" PRIx32 ") is not aligned with 1M!",
addr);
return -1;
}

if (!_IS_ALIGNED(size, SIZE_1M)) {
EMSG("region size(0x%" PRIx32 ") is not aligned with 1M!",
size);
return -1;
}

RANGE_SIZE_TO_CODE(size, sizecode, i);
if (sizecode == INVALID_SIZE_CODE) {
EMSG("not valid region size(2^n)! size:0x%" PRIx32, size);
return -1;
}

valid_range = _find_valid_range();
if (valid_range == -1) {
EMSG("ERR: can't find valid range!");
return -1;
}

data = read32(MCU_TZ_RANGE_LOW_REG(valid_range));

TZ_SET_VALID(data);
TZ_SET_PERM(data, perm);
TZ_SET_AREA_LEN_CODE(data, sizecode);
TZ_SET_START_ADDR_L(data, addr);

if (!valid_range) {
/* Set Undefine Range RW */
TZ_SET_UR_PERM(data, RW_PERM);
TZ_SET_UR_RZ_EN(data, 0);
}

write32(data, MCU_TZ_RANGE_LOW_REG(valid_range));

return 0;
}

static void _dump_range(void)
{
uint32_t i;
uint32_t tmp;
uint32_t __maybe_unused sizecode_read;
uint32_t __maybe_unused sizem;
uint32_t __maybe_unused addr_read;
uint32_t __maybe_unused perm_read;

for (i = 0; i < MAX_RANGE_NUM; i++) {
tmp = read32(MCU_TZ_RANGE_LOW_REG(i));

if (TZ_IS_VALID(tmp)) {
TZ_GET_PERM(tmp, perm_read);
TZ_GET_AREA_LEN_CODE(tmp, sizecode_read);
TZ_GET_START_ADDR_L(tmp, addr_read);

DMSG("Range Num%" PRIu32
": Reg 0x%" PRIx64 " = 0x%" PRIx32,
i, MCU_TZ_RANGE_LOW_REG(i), tmp);
DMSG("AddrL: 0x%08" PRIx32, addr_read);
DMSG("Size: %" PRIu32 "M", (0x1 << sizecode_read));
DMSG("Perm: %" PRIu32, perm_read);
}
}
}

static void _set_range(uint32_t addr, uint32_t size, uint32_t perm)
{
uint32_t rgn_addr = addr;
uint32_t rgn_size = size;
/* minimum region size is 1M and must be times of 1M */
uint32_t p = 0x100000;

while (1) {
if ((p * 2) > rgn_size) {
set_range(rgn_addr, p, perm);
rgn_addr += p;
rgn_size -= p;
if (rgn_size == 0)
break;
p = 0x100000;
} else
p <<= 1;
}
}

static TEE_Result init_sec_perf(void)
{
uint32_t tmp;

/* Set Secure Memory Region */
DMSG("sec-rgn size: ra = 0x%" PRIx32 ", size = 0x%" PRIx64,
RA_ADDR, RA_SIZE);
_set_range(RA_ADDR, RA_SIZE, RA_PERM);

/* Close TZ register modification */
TZ_LOCK_MC(tmp);

_dump_range();

return TEE_SUCCESS;
}

service_init(init_sec_perf);
11 changes: 9 additions & 2 deletions core/arch/arm/plat-marvell/conf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ core_arm32-platform-aflags += -mfpu=neon
ifeq ($(PLATFORM_FLAVOR),armada7k8k)
include core/arch/arm/cpu/cortex-armv8-0.mk
platform-debugger-arm := 1
$(call force,CFG_8250_UART,y)
endif

ifeq ($(PLATFORM_FLAVOR),armada3700)
include core/arch/arm/cpu/cortex-armv8-0.mk
platform-debugger-arm := 1
$(call force,CFG_MVEBU_UART,y)
$(call force,CFG_ARM_GICV3,y)
endif

ifeq ($(platform-debugger-arm),1)
Expand All @@ -15,10 +23,9 @@ platform-aflags-debug-info = -gdwarf-2
endif

$(call force,CFG_WITH_ARM_TRUSTED_FW,y)

$(call force,CFG_ARM64_core,y)
$(call force,CFG_GENERIC_BOOT,y)
$(call force,CFG_GIC,y)
$(call force,CFG_8250_UART,y)
$(call force,CFG_PM_STUBS,y)
$(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y)
$(call force,CFG_CORE_CLUSTER_SHIFT,1)
Expand Down
13 changes: 13 additions & 0 deletions core/arch/arm/plat-marvell/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
#include <arm.h>
#include <console.h>
#include <drivers/gic.h>
#if defined(PLATFORM_FLAVOR_armada7k8k)
#include <drivers/serial8250_uart.h>
#elif defined(PLATFORM_FLAVOR_armada3700)
#include <drivers/mvebu_uart.h>
#endif
#include <keep.h>
#include <kernel/generic_boot.h>
#include <kernel/pm_stubs.h>
Expand Down Expand Up @@ -58,7 +62,11 @@ static const struct thread_handlers handlers = {
};

static struct gic_data gic_data;
#if defined(PLATFORM_FLAVOR_armada7k8k)
static struct serial8250_uart_data console_data;
#elif defined(PLATFORM_FLAVOR_armada3700)
static struct mvebu_uart_data console_data;
#endif

const struct thread_handlers *generic_boot_get_handlers(void)
{
Expand Down Expand Up @@ -96,7 +104,12 @@ static void main_fiq(void)

void console_init(void)
{
#if defined(PLATFORM_FLAVOR_armada7k8k)
serial8250_uart_init(&console_data, CONSOLE_UART_BASE,
CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE);
#elif defined(PLATFORM_FLAVOR_armada3700)
mvebu_uart_init(&console_data, CONSOLE_UART_BASE,
CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE);
#endif
register_serial_console(&console_data.chip);
}
Loading