From bfc0f1a852ba5b6ac98cf9e60a17488993dd041b Mon Sep 17 00:00:00 2001 From: Harikrishna Date: Fri, 19 Jun 2026 16:30:04 +0530 Subject: [PATCH 1/4] drivers: qcom: rng: Consolidate PRNG into generic RNG driver - Rename prng.c to qcom-rng.c for platform-agnostic naming - Move driver source inclusion to parent qcom/sub.mk with CFG_QCOM_RNG flag - Simplify driver by using generic RNG naming conventions Change-Id: I5b262d5038e10aca7f6b4e8ee93847006b1b0a9f Signed-off-by: Harikrishna --- .../qcom/{prng/prng.c => rng/qcom-rng.c} | 34 +++++++++---------- core/drivers/qcom/rng/sub.mk | 7 ++++ core/drivers/qcom/sub.mk | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) rename core/drivers/qcom/{prng/prng.c => rng/qcom-rng.c} (58%) create mode 100644 core/drivers/qcom/rng/sub.mk diff --git a/core/drivers/qcom/prng/prng.c b/core/drivers/qcom/rng/qcom-rng.c similarity index 58% rename from core/drivers/qcom/prng/prng.c rename to core/drivers/qcom/rng/qcom-rng.c index 8f50f56b7..bf4ab73ae 100644 --- a/core/drivers/qcom/prng/prng.c +++ b/core/drivers/qcom/rng/qcom-rng.c @@ -10,19 +10,17 @@ #include #include -#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_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) @@ -31,22 +29,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; } - 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; } @@ -60,14 +58,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); diff --git a/core/drivers/qcom/rng/sub.mk b/core/drivers/qcom/rng/sub.mk new file mode 100644 index 000000000..c622cd336 --- /dev/null +++ b/core/drivers/qcom/rng/sub.mk @@ -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 diff --git a/core/drivers/qcom/sub.mk b/core/drivers/qcom/sub.mk index b7a931564..a449af31e 100644 --- a/core/drivers/qcom/sub.mk +++ b/core/drivers/qcom/sub.mk @@ -5,7 +5,7 @@ # srcs-$(CFG_QCOM_RAMBLUR_PIMEM_V3) += ramblur/ramblur_pimem_v3.c -srcs-$(CFG_QCOM_PRNG) += prng/prng.c +srcs-$(CFG_QCOM_RNG) += rng/qcom-rng.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)) From 0428df988c8ca77e03a36f7206dcf06ab340c967 Mon Sep 17 00:00:00 2001 From: Harikrishna Date: Fri, 19 Jun 2026 16:33:00 +0530 Subject: [PATCH 2/4] plat-qcom: Enable consolidated RNG driver for QCOM platforms - Update from CFG_QCOM_PRNG to unified CFG_QCOM_RNG - Configure RNG_REG_BASE for PRNG variant - Enable CFG_HWRNG_PTA configuration for ipq52xx - When HWRNG_PTA is enabled: - Disable CFG_WITH_SOFTWARE_PRNG to prevent fallback - Force enable CFG_QCOM_RNG to use hardware QRNG driver - Configure HWRNG quality to 1024 bits entropy - Set HWRNG rate to 0 (unlimited) Signed-off-by: Harikrishna --- core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk | 10 ++++++++++ core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h | 2 ++ core/arch/arm/plat-qcom/hoya/arch_config.h | 2 ++ core/arch/arm/plat-qcom/hoya/qcom-arch.mk | 2 +- core/drivers/qcom/rng/qcom-rng.c | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk index 8b1d18043..db46fe6ff 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk +++ b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk @@ -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 diff --git a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h index 17008a0a0..7eabe3a09 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h +++ b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h @@ -20,4 +20,6 @@ #define IMEM_BASE UL(0x8600000) #define IMEM_SIZE UL(0x18000) +#define RNG_REG_BASE UL(0x4C5000) + #endif /* TARGET_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/hoya/arch_config.h b/core/arch/arm/plat-qcom/hoya/arch_config.h index 8848825cb..07563fdb0 100644 --- a/core/arch/arm/plat-qcom/hoya/arch_config.h +++ b/core/arch/arm/plat-qcom/hoya/arch_config.h @@ -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) + #endif /* ARCH_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/hoya/qcom-arch.mk b/core/arch/arm/plat-qcom/hoya/qcom-arch.mk index 59e372983..17e0fd346 100644 --- a/core/arch/arm/plat-qcom/hoya/qcom-arch.mk +++ b/core/arch/arm/plat-qcom/hoya/qcom-arch.mk @@ -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 diff --git a/core/drivers/qcom/rng/qcom-rng.c b/core/drivers/qcom/rng/qcom-rng.c index bf4ab73ae..f7bb764ca 100644 --- a/core/drivers/qcom/rng/qcom-rng.c +++ b/core/drivers/qcom/rng/qcom-rng.c @@ -14,6 +14,7 @@ #define RNG_STATUS 0x4 #define RNG_STATUS_DATA_AVAIL_BMSK 0x1 +#define RNG_REG_SIZE 0x1000 #define RNG_TIMEOUT_US 1000000 static struct { From 7c42f97f447e5a0aef42ac872df132dad4174451 Mon Sep 17 00:00:00 2001 From: Harikrishna Date: Tue, 23 Jun 2026 15:58:05 +0530 Subject: [PATCH 3/4] drivers: qcom: wdog: Add secure watchdog driver for Bobcat family QCOM platforms manage secure watchdog via driver_init() without framework registration. This is sufficient as QCOM currently does not require HLOS control over the secure watchdog. The implementation maintains separation between secure and non-secure world watchdog management. Key implementation details: - Maps APSS_WDT_TMR2_BASE into secure I/O memory - Configures bark timeout (6s) and bite timeout (22s) using a 32 KHz watchdog clock, converting milliseconds to hardware ticks - Registers qcom_sec_wdog_bark_handler() for SEC_WDOG_BARK_INT_ID via interrupt_create_handler() - Bark handler pets the watchdog by writing to WDOG_RESET register Signed-off-by: Harikrishna --- core/drivers/qcom/sub.mk | 1 + core/drivers/qcom/wdt/wdt.c | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 core/drivers/qcom/wdt/wdt.c diff --git a/core/drivers/qcom/sub.mk b/core/drivers/qcom/sub.mk index a449af31e..176ccd9f4 100644 --- a/core/drivers/qcom/sub.mk +++ b/core/drivers/qcom/sub.mk @@ -6,6 +6,7 @@ srcs-$(CFG_QCOM_RAMBLUR_PIMEM_V3) += ramblur/ramblur_pimem_v3.c 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)) diff --git a/core/drivers/qcom/wdt/wdt.c b/core/drivers/qcom/wdt/wdt.c new file mode 100644 index 000000000..46d07f957 --- /dev/null +++ b/core/drivers/qcom/wdt/wdt.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * QCOM Secure Watchdog Driver + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +register_phys_mem_pgdir(MEM_AREA_IO_SEC, WDT_TMR_BASE, + 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); + From c33815dd29fb64f218e96322d578ea8888179e1f Mon Sep 17 00:00:00 2001 From: Harikrishna Date: Fri, 19 Jun 2026 16:48:54 +0530 Subject: [PATCH 4/4] plat-qcom: Enable sec wdog config for Bobcat family - CFG_QCOM_SEC_WDOG enabled in bobcat/arch.mk for all Bobcat targets - Per-target hardware addresses (WDT_TMR_BASE, WDT_BARK_INT_ID, WDT_RESET_REG_OFFSET) defined in target-specific target_config.h files: - ipq96xx/ipq54xx: base=0x0F411000, bark_int=0x36 - ipq52xx: base=0x0B117000, bark_int=0x23 Signed-off-by: Harikrishna --- core/arch/arm/plat-qcom/bobcat/arch.mk | 4 ++++ core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h | 4 ++++ core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 core/arch/arm/plat-qcom/bobcat/arch.mk diff --git a/core/arch/arm/plat-qcom/bobcat/arch.mk b/core/arch/arm/plat-qcom/bobcat/arch.mk new file mode 100644 index 000000000..e3b71bcb2 --- /dev/null +++ b/core/arch/arm/plat-qcom/bobcat/arch.mk @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + +CFG_QCOM_SEC_WDOG ?= y diff --git a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h index 7eabe3a09..0bcfbb5f5 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h +++ b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h @@ -22,4 +22,8 @@ #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 */ diff --git a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h index b3eb10732..03e0a2f43 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h +++ b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h @@ -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 */