Skip to content

Commit

Permalink
plat-telechips: Add initial support for Telechips platform (TCC805x)
Browse files Browse the repository at this point in the history
This is the initial support for Telechips Platform (TCC805x).

* xtest results (-l 15):
| 334474 subtests of which 0 failed
| 108 test cases of which 0 failed
| 0 test cases were skipped
| TEE test application done!

* Compiled with:
| make PLATFORM=telechips-tcc805x

Signed-off-by: Sungmin Han <[email protected]>
Signed-off-by: GY Hwang <[email protected]>
Acked-by: Jerome Forissier <[email protected]>
Acked-by: Jens Wiklander <[email protected]>
Acked-by: Etienne Carriere <[email protected]>
  • Loading branch information
meeneemaru authored and jforissier committed Jan 7, 2025
1 parent 7122f38 commit c1e6570
Show file tree
Hide file tree
Showing 16 changed files with 898 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ jobs:
_make PLATFORM=nuvoton
_make PLATFORM=d06
_make PLATFORM=d06 CFG_HISILICON_ACC_V3=y
_make PLATFORM=telechips-tcc805x
export ARCH=riscv
unset CROSS_COMPILE32
Expand Down
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ R: Neal Liu <[email protected]> [@Neal-liu]
S: Maintained
F: core/arch/arm/plat-aspeed/

Telechips TCC805x
R: Sungmin Han <[email protected]> [@meeneemaru]
R: GY Hwang <[email protected]> [@hwang-telechips]
S: Maintained
F: core/arch/arm/plat-telechips/
F: core/drivers/openedges_omc.c

RISC-V
R: Marouene Boubakri <[email protected]> [@maroueneboubakri]
S: Maintained
Expand Down
38 changes: 38 additions & 0 deletions core/arch/arm/plat-telechips/conf.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ifeq ($(PLATFORM_FLAVOR),tcc805x)
CFG_PL011 ?= y
CFG_OPENEDGES_OMC ?= y
CFG_ARM_SMCCC_TRNG ?= y

$(call force,CFG_CORE_LARGE_PHYS_ADDR,y)
$(call force,CFG_CORE_ARM64_PA_BITS,35)
$(call force,CFG_TEE_CORE_NB_CORE,4)

CFG_TZDRAM_START ?= 0x2E000000
CFG_TZDRAM_SIZE ?= 0x02000000

include core/arch/arm/cpu/cortex-armv8-0.mk
$(call force,CFG_ARM64_core,y)

TCMKTOOL_IMGNAME ?= A72-OPTEE
else
$(error Unsupported PLATFORM_FLAVOR "$(PLATFORM_FLAVOR)")
endif

$(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y)
$(call force,CFG_GIC,y)
$(call force,CFG_CACHE_API,y)
$(call force,CFG_CORE_RESERVED_SHM,n)

ifeq ($(platform-flavor-armv8),1)
$(call force,CFG_WITH_ARM_TRUSTED_FW,y)
$(call force,CFG_CRYPTO_WITH_CE,y)
endif

CFG_NUM_THREADS ?= $(CFG_TEE_CORE_NB_CORE)
CFG_SECSTOR_TA ?= n
CFG_CORE_HEAP_SIZE ?= 1048576
CFG_WITH_STATS ?= y

ifeq ($(CFG_RPMB_FS),y)
CFG_IN_TREE_EARLY_TAS += avb/023f8f1a-292a-432b-8fc4-de8471358067
endif
14 changes: 14 additions & 0 deletions core/arch/arm/plat-telechips/drivers/include/drivers/tcc_otp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2024, Telechips Inc.
*/

#ifndef __DRIVERS_TCC_OTP_H
#define __DRIVERS_TCC_OTP_H

#include <tee_api_types.h>

TEE_Result tcc_otp_read_128(uint32_t offset, uint32_t *buf);
TEE_Result tcc_otp_write_128(uint32_t offset, const uint32_t *buf);

#endif /* __DRIVERS_TCC_OTP_H */
1 change: 1 addition & 0 deletions core/arch/arm/plat-telechips/drivers/sub.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
srcs-y += tcc_otp.c
144 changes: 144 additions & 0 deletions core/arch/arm/plat-telechips/drivers/tcc_otp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2024, Telechips Inc.
*/

#include <drivers/tcc_otp.h>
#include <io.h>
#include <kernel/delay.h>
#include <mm/core_memprot.h>
#include <otprom.h>
#include <string.h>

#define OTP_CTRL_SIZE U(0x1000)
#define OTP_CMD_SIZE U(0x1000)

#define GENERAL_STATUS U(0x0)
#define READ_STATUS U(0x4)
#define PROG_STATUS U(0x8)
#define OTP_ADDRESS U(0x10)
#define OTP_CONTROL U(0x14)
#define READ_DATA_PAYLOAD0 U(0x20)
#define READ_DATA_PAYLOAD1 U(0x24)
#define READ_DATA_PAYLOAD2 U(0x28)
#define READ_DATA_PAYLOAD3 U(0x2C)
#define READ_ADMIN_INFO0 U(0x30)
#define READ_ADMIN_INFO1 U(0x34)
#define READ_ADMIN_INFO2 U(0x38)
#define READ_ADMIN_INFO3 U(0x3C)
#define PROG_DATA_PAYLOAD0 U(0x40)
#define PROG_DATA_PAYLOAD1 U(0x44)
#define PROG_DATA_PAYLOAD2 U(0x48)
#define PROG_DATA_PAYLOAD3 U(0x4C)
#define PROG_ADMIN_INFO0 U(0x50)
#define PROG_ADMIN_INFO1 U(0x54)
#define PROG_ADMIN_INFO2 U(0x58)
#define PROG_ADMIN_INFO3 U(0x5C)

/* GENERAL_STATUS */
#define STATUS_READY BIT(0)

/* READ_STATUS */
#define DATA_ERR BIT(3)
#define PERMISSION_ERR BIT(0)

/* OTP_CONTROL Register */
#define CTRL_DONE BIT(16)
#define CTRL_START BIT(0)
#define CTRL_CMD_PROG SHIFT_U32(0xA, 4)
#define CTRL_CMD_READ SHIFT_U32(0xF, 4)

/* Admin Info */
#define ADMIN_VALID BIT(0)

/* Write Protection Control */
#define EXT_WP BIT(30)
#define SOFT_WP BIT(3)

#define IS_16BYTE_ALIGNED(x) IS_ALIGNED(x, 16)

register_phys_mem(MEM_AREA_IO_SEC, OTP_CMD_BASE, OTP_CMD_SIZE);

static void wait_for_ready(vaddr_t reg)
{
while (!(io_read32(reg + GENERAL_STATUS) & STATUS_READY))
udelay(1);
}

static void wait_for_done(vaddr_t reg)
{
while (!(io_read32(reg + OTP_CONTROL) & CTRL_DONE))
udelay(1);
}

TEE_Result tcc_otp_read_128(uint32_t offset, uint32_t *buf)
{
vaddr_t reg = (vaddr_t)phys_to_virt_io(OTP_CMD_BASE, OTP_CMD_SIZE);
uint32_t status = 0;
uint32_t admin_info0 = 0;

if (!IS_16BYTE_ALIGNED(offset) || offset >= OTPROM_128_LIMIT ||
offset < OTPROM_128_START || !buf || !reg) {
EMSG("Invalid parameters");
return TEE_ERROR_BAD_PARAMETERS;
}

wait_for_ready(reg);
io_write32(reg + OTP_ADDRESS, offset);
io_write32(reg + OTP_CONTROL, CTRL_CMD_READ | CTRL_START);
wait_for_done(reg);

admin_info0 = io_read32(reg + READ_ADMIN_INFO0);
if (!(admin_info0 & ADMIN_VALID)) {
if (!admin_info0 && !io_read32(reg + READ_STATUS))
return TEE_ERROR_NO_DATA;
return TEE_ERROR_BAD_STATE;
}

status = io_read32(reg + READ_STATUS);
if (status & (DATA_ERR | PERMISSION_ERR)) {
EMSG("Failed to read OTP (%#"PRIx32")", status);
return TEE_ERROR_BAD_STATE;
}

buf[0] = io_read32(reg + READ_DATA_PAYLOAD0);
buf[1] = io_read32(reg + READ_DATA_PAYLOAD1);
buf[2] = io_read32(reg + READ_DATA_PAYLOAD2);
buf[3] = io_read32(reg + READ_DATA_PAYLOAD3);

return TEE_SUCCESS;
}

TEE_Result tcc_otp_write_128(uint32_t offset, const uint32_t *buf)
{
vaddr_t reg = (vaddr_t)phys_to_virt_io(OTP_CMD_BASE, OTP_CMD_SIZE);
vaddr_t ctrl = (vaddr_t)phys_to_virt_io(OTP_CTRL_BASE, OTP_CTRL_SIZE);

if (!IS_16BYTE_ALIGNED(offset) || offset >= OTPROM_128_LIMIT ||
offset < OTPROM_128_START || !buf || !reg) {
EMSG("Invalid parameters");
return TEE_ERROR_BAD_PARAMETERS;
}

if (io_read32(ctrl) & EXT_WP) {
EMSG("EXT_WP is high");
return TEE_ERROR_BAD_STATE;
}

wait_for_ready(reg);
io_clrbits32(ctrl, SOFT_WP);
io_write32(reg + OTP_ADDRESS, offset);
io_write32(reg + PROG_DATA_PAYLOAD0, buf[0]);
io_write32(reg + PROG_DATA_PAYLOAD1, buf[1]);
io_write32(reg + PROG_DATA_PAYLOAD2, buf[2]);
io_write32(reg + PROG_DATA_PAYLOAD3, buf[3]);
io_write32(reg + PROG_ADMIN_INFO0, 0);
io_write32(reg + PROG_ADMIN_INFO1, 0);
io_write32(reg + PROG_ADMIN_INFO2, 0);
io_write32(reg + PROG_ADMIN_INFO3, 0);
io_write32(reg + OTP_CONTROL, CTRL_CMD_PROG | CTRL_START);
wait_for_done(reg);
io_setbits32(ctrl, SOFT_WP);

return TEE_SUCCESS;
}
9 changes: 9 additions & 0 deletions core/arch/arm/plat-telechips/link.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include core/arch/arm/kernel/link.mk

all: $(link-out-dir)/optee.rom
cleanfiles += $(link-out-dir)/optee.rom
$(link-out-dir)/optee.rom: $(link-out-dir)/tee-pager_v2.bin
@$(cmd-echo-silent) ' GEN $@'
$(q)$(PYTHON3) core/arch/arm/plat-telechips/scripts/tcmktool.py $< $@ $(TCMKTOOL_IMGNAME) \
$(CFG_OPTEE_REVISION_MAJOR).$(CFG_OPTEE_REVISION_MINOR)$(CFG_OPTEE_REVISION_EXTRA) \
$(CFG_TZDRAM_START) $(PLATFORM_FLAVOR)
86 changes: 86 additions & 0 deletions core/arch/arm/plat-telechips/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2024, Telechips Inc.
*/

#include <console.h>
#include <crypto/crypto.h>
#include <drivers/gic.h>
#include <drivers/pl011.h>
#include <drivers/tcc_otp.h>
#include <kernel/boot.h>
#include <kernel/tee_common_otp.h>
#include <otprom.h>
#include <platform_config.h>

register_phys_mem(MEM_AREA_IO_SEC, TCC_IO_BASE, TCC_IO_SIZE);
#if defined(TZC_BASE)
register_phys_mem(MEM_AREA_IO_SEC, TZC_BASE, TZC_SIZE);
#endif

register_ddr(DRAM0_BASE, DRAM0_SIZE);
#if defined(DRAM1_BASE)
register_ddr(DRAM1_BASE, DRAM1_SIZE);
#endif

static bool huk_is_ready;
static uint32_t plat_huk[OTP_DATA_TEE_HUK_SIZE / sizeof(uint32_t)];

void boot_primary_init_intc(void)
{
gic_init(GICC_BASE, GICD_BASE);
}

void boot_secondary_init_intc(void)
{
gic_init_per_cpu();
}

void plat_console_init(void)
{
#if defined(CFG_PL011)
static struct pl011_data console_data;

pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ,
CONSOLE_BAUDRATE);
register_serial_console(&console_data.chip);
#endif
}

TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
{
static_assert(sizeof(plat_huk) == sizeof(hwkey->data));

if (!huk_is_ready)
return TEE_ERROR_GENERIC;

memcpy(hwkey->data, plat_huk, OTP_DATA_TEE_HUK_SIZE);
return TEE_SUCCESS;
}

static TEE_Result init_huk(void)
{
TEE_Result res = TEE_ERROR_GENERIC;

res = tcc_otp_read_128(OTP_DATA_TEE_HUK_OFFSET, plat_huk);
if (res == TEE_ERROR_NO_DATA) {
IMSG("There is no HUK in OTP. Starting HUK Provisioning");
if (!crypto_rng_read(plat_huk, OTP_DATA_TEE_HUK_SIZE)) {
tcc_otp_write_128(OTP_DATA_TEE_HUK_OFFSET, plat_huk);
res = tcc_otp_read_128(OTP_DATA_TEE_HUK_OFFSET,
plat_huk);
if (res != TEE_SUCCESS)
EMSG("Failed to store HUK to OTP");
} else {
EMSG("Failed to generate random number for HUK");
}
}

if (res == TEE_SUCCESS)
huk_is_ready = true;
else
EMSG("Failed to get HUK from OTP");

return res;
}
service_init(init_huk);
Loading

0 comments on commit c1e6570

Please sign in to comment.