Skip to content
Open
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
4 changes: 4 additions & 0 deletions core/arch/arm/plat-qcom/bobcat/arch.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.

CFG_QCOM_SEC_WDOG ?= y
10 changes: 10 additions & 0 deletions core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,13 @@ CFG_QCOM_DIAG_LOG ?= $(if $(filter y,$(CFG_TEE_CORE_DEBUG)),y,n)
CFG_TZDRAM_START ?= 0x87D80000
CFG_TZDRAM_SIZE ?= 0x280000
CFG_TEE_RAM_VA_SIZE ?= 0x280000

CFG_QCOM_DIAG_LOG ?= $(if $(filter y,$(CFG_TEE_CORE_DEBUG)),y,n)

CFG_HWRNG_PTA ?= y
ifeq ($(CFG_HWRNG_PTA),y)
$(call force,CFG_WITH_SOFTWARE_PRNG,n)
$(call force,CFG_QCOM_RNG,y)
CFG_HWRNG_QUALITY ?= 1024
CFG_HWRNG_RATE ?= 0
endif
6 changes: 6 additions & 0 deletions core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@
#define IMEM_BASE UL(0x8600000)
Comment thread
thariaruchamy-bit marked this conversation as resolved.
#define IMEM_SIZE UL(0x18000)

#define RNG_REG_BASE UL(0x4C5000)

#define WDT_TMR_BASE UL(0x0B117000)
#define WDT_RESET_REG_OFFSET UL(0x4)
#define WDT_BARK_INT_ID UL(0x23)

#endif /* TARGET_CONFIG_H */
4 changes: 4 additions & 0 deletions core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@
#define IMEM_BASE UL(0x8600000)
#define IMEM_SIZE UL(0x20000)

#define WDT_TMR_BASE UL(0x0F411000)
#define WDT_RESET_REG_OFFSET UL(0x4)
#define WDT_BARK_INT_ID UL(0x36)

#endif /* TARGET_CONFIG_H */
2 changes: 2 additions & 0 deletions core/arch/arm/plat-qcom/hoya/arch_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@
#define DIAG_LOG_START_INFO (IMEM_BASE + IMEM_DIAG_OFFSET)
#define TCSR_BOOT_MISC_DETECT UL(0x1FD3000)

#define RNG_REG_BASE UL(0x010D1000)
Comment thread
thariaruchamy-bit marked this conversation as resolved.

#endif /* ARCH_CONFIG_H */
2 changes: 1 addition & 1 deletion core/arch/arm/plat-qcom/hoya/qcom-arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ $(call force,CFG_TEE_CORE_NB_CORE,8)
$(call force,CFG_QCOM_RAMBLUR_PIMEM_V3,y)
CFG_QCOM_RAMBLUR_TA_WINDOW_ID ?= 2

$(call force,CFG_QCOM_PRNG,y)
$(call force,CFG_QCOM_RNG,y)
$(call force,CFG_ARM_GICV3,y)

CFG_TZDRAM_START ?= 0x1c300000
Expand Down
35 changes: 17 additions & 18 deletions core/drivers/qcom/prng/prng.c → core/drivers/qcom/rng/qcom-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@
#include <platform_config.h>
Comment thread
thariaruchamy-bit marked this conversation as resolved.
#include <rng_support.h>

#define SEC_PRNG_REG_SIZE 0x1000
#define RNG_DATA_OUT 0x0
#define RNG_STATUS 0x4
#define RNG_STATUS_DATA_AVAIL_BMSK 0x1

#define SEC_PRNG_DATA_OUT 0x0
#define SEC_PRNG_STATUS 0x4
#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1

#define PRNG_TIMEOUT_US 1000000
#define RNG_REG_SIZE 0x1000
Comment thread
thariaruchamy-bit marked this conversation as resolved.
#define RNG_TIMEOUT_US 1000000

static struct {
paddr_t pa;
vaddr_t va;
} prng = {
.pa = SEC_PRNG_REG_BASE,
} rng = {
.pa = RNG_REG_BASE,
};

TEE_Result hw_get_random_bytes(void *buf, size_t len)
Expand All @@ -31,22 +30,22 @@ TEE_Result hw_get_random_bytes(void *buf, size_t len)
uint32_t val = 0;
uint64_t to = 0;

if (!prng.va)
if (!rng.va)
return TEE_ERROR_NOT_SUPPORTED;

if (!out || !len)
return TEE_ERROR_BAD_PARAMETERS;

to = timeout_init_us(PRNG_TIMEOUT_US);
to = timeout_init_us(RNG_TIMEOUT_US);
while (len) {
if (!(io_read32(prng.va + SEC_PRNG_STATUS) &
SEC_PRNG_STATUS_DATA_AVAIL_BMSK)) {
if (!(io_read32(rng.va + RNG_STATUS) &
RNG_STATUS_DATA_AVAIL_BMSK)) {
if (timeout_elapsed(to))
return TEE_ERROR_BUSY;
continue;
}
Comment thread
thariaruchamy-bit marked this conversation as resolved.

while ((val = io_read32(prng.va + SEC_PRNG_DATA_OUT)) == 0) {
while ((val = io_read32(rng.va + RNG_DATA_OUT)) == 0) {
if (timeout_elapsed(to))
return TEE_ERROR_BUSY;
}
Expand All @@ -60,14 +59,14 @@ TEE_Result hw_get_random_bytes(void *buf, size_t len)
return TEE_SUCCESS;
}

static TEE_Result qcom_prng_init(void)
static TEE_Result rng_init(void)
{
prng.va = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, prng.pa,
SEC_PRNG_REG_SIZE);
if (!prng.va)
rng.va = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, rng.pa,
RNG_REG_SIZE);
if (!rng.va)
return TEE_ERROR_GENERIC;

return TEE_SUCCESS;
}

early_init(qcom_prng_init);
early_init(rng_init);
7 changes: 7 additions & 0 deletions core/drivers/qcom/rng/sub.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
#

global-incdirs-y += .
srcs-$(CFG_QCOM_RNG) += qcom-rng.c
3 changes: 2 additions & 1 deletion core/drivers/qcom/sub.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#

srcs-$(CFG_QCOM_RAMBLUR_PIMEM_V3) += ramblur/ramblur_pimem_v3.c
srcs-$(CFG_QCOM_PRNG) += prng/prng.c
Comment thread
thariaruchamy-bit marked this conversation as resolved.
srcs-$(CFG_QCOM_RNG) += rng/qcom-rng.c
srcs-$(CFG_QCOM_SEC_WDOG) += wdt/wdt.c

$(eval $(call cfg-depends-all,CFG_QCOM_QFPROM,CFG_QCOM_CMD_DB CFG_QCOM_RPMH_CLIENT))
$(eval $(call cfg-depends-all,CFG_QCOM_RPMH_CLIENT,CFG_QCOM_CMD_DB))
Expand Down
116 changes: 116 additions & 0 deletions core/drivers/qcom/wdt/wdt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* QCOM Secure Watchdog Driver
*
*/

#include <arm.h>
#include <initcall.h>
#include <io.h>
#include <kernel/interrupt.h>
#include <kernel/panic.h>
#include <mm/core_memprot.h>
#include <platform_config.h>
#include <trace.h>
#include <util.h>

register_phys_mem_pgdir(MEM_AREA_IO_SEC, WDT_TMR_BASE,
Comment thread
thariaruchamy-bit marked this conversation as resolved.
CORE_MMU_PGDIR_SIZE);

#define WDT_CTL_OFFSET 0x08
#define WDT_BARK_TIME_OFFSET 0x10
#define WDT_BITE_TIME_OFFSET 0x14

#define WDT_CTL_INT_ENABLE_SHFT 0
#define WDT_CTL_UNMASKED_INT_ENABLE_SHFT 1

#define WDT_BARK_TIME_RMSK 0xFFFFFU
#define WDT_BITE_TIME_RMSK 0xFFFFFU

#define WDT_CLK_HZ 32000U

#define WDT_BARK_TIME_MS 6000U
#define WDT_BITE_TIME_MS 22000U

static vaddr_t wdt_base;

static uint32_t ms_to_ticks_wdt(uint32_t ms)
{
return (uint32_t)(((uint64_t)ms * WDT_CLK_HZ) / 1000U);
}

static void wdt_enable(bool enable)
{
io_write32(wdt_base + WDT_CTL_OFFSET,
UINT32_C(1) << WDT_CTL_UNMASKED_INT_ENABLE_SHFT
| (enable ? UINT32_C(1) : UINT32_C(0))
<< WDT_CTL_INT_ENABLE_SHFT);
}

static void wdt_reset(void)
{
io_write32(wdt_base + WDT_RESET_REG_OFFSET, 1);
}

static void wdt_start(uint32_t bark_timeout, uint32_t bite_timeout)
{
/* Zero timeouts are not allowed, ensure timeouts are > 0. */
bark_timeout = MAX(bark_timeout, 0x1U);
bite_timeout = MAX(bite_timeout, 0x1U);

bark_timeout = ms_to_ticks_wdt(bark_timeout);
bite_timeout = ms_to_ticks_wdt(bite_timeout);

/* Timeouts have a ceiling value */
bark_timeout = MIN(bark_timeout, (uint32_t)(WDT_BARK_TIME_RMSK));
bite_timeout = MIN(bite_timeout, (uint32_t)(WDT_BITE_TIME_RMSK));

wdt_enable(false);

io_write32(wdt_base + WDT_BARK_TIME_OFFSET, bark_timeout);
io_write32(wdt_base + WDT_BITE_TIME_OFFSET, bite_timeout);

wdt_enable(true);

wdt_reset();
}

static enum itr_return
wdt_bark_handler(struct itr_handler *h __unused)
{
io_write32(wdt_base + WDT_RESET_REG_OFFSET, 1);

return ITRR_HANDLED;
}

static TEE_Result wdt_init(void)
{
TEE_Result res = TEE_SUCCESS;
struct itr_handler *handler = NULL;

wdt_base = (vaddr_t)phys_to_virt(WDT_TMR_BASE,
MEM_AREA_IO_SEC, 1);
if (!wdt_base) {
EMSG("wdt: Failed to map watchdog registers");
return TEE_ERROR_GENERIC;
}

wdt_start(WDT_BARK_TIME_MS, WDT_BITE_TIME_MS);

res = interrupt_create_handler(interrupt_get_main_chip(),
WDT_BARK_INT_ID,
wdt_bark_handler,
0u, 0u, &handler);
if (res != TEE_SUCCESS) {
EMSG("wdt: Failed to register bark handler (err=0x%x)",
res);
return res;
}

return TEE_SUCCESS;
}

driver_init(wdt_init);