feat(rcar3): populate kaslr-seed in next stage DT
The SCEG CC6.3S which contains TRNG is only accessible from secure
world. Pull 8 random bytes out of the TRNG and pass them to the next
stage via DT fragment as /chosen/kaslr-seed property, so Linux can
use those random bytes to initialize KASLR in case it is compiled
with CONFIG_RANDOMIZE_BASE .
Linux before this patch prints early on boot:
KASLR disabled due to lack of seed
Linux after this patch prints early on boot:
KASLR enabled
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Change-Id: Ie05473e4e15d348febaca208247541e8a1532534
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 41031d6..c548240 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -756,6 +756,69 @@
#endif
}
+static void bl2_add_kaslr_seed(void)
+{
+ uint32_t cnt, isr, prr;
+ uint64_t seed;
+ int ret, node;
+
+ /* SCEG is only available on H3/M3-W/M3-N */
+ prr = mmio_read_32(RCAR_PRR);
+ switch (prr & PRR_PRODUCT_MASK) {
+ case PRR_PRODUCT_H3:
+ case PRR_PRODUCT_M3:
+ case PRR_PRODUCT_M3N:
+ break;
+ default:
+ return;
+ }
+
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SW_RESET_REG_ADDR,
+ CC63_TRNG_SW_RESET_REG_SET);
+
+ do {
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CLK_ENABLE_REG_ADDR,
+ CC63_TRNG_CLK_ENABLE_REG_SET);
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR,
+ CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+ cnt = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR);
+ } while (cnt != CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CONFIG_REG_ADDR,
+ CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH);
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_DEBUG_CONTROL_REG_ADDR,
+ CC63_TRNG_DEBUG_CONTROL_REG_80090B);
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+ CC63_TRNG_SOURCE_ENABLE_REG_SET);
+
+ do {
+ isr = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_ISR_REG_ADDR);
+ if ((isr & CC63_TRNG_ISR_REG_AUTOCORR_ERR) != 0U) {
+ panic();
+ }
+ } while ((isr & CC63_TRNG_ISR_REG_EHR_VALID) == 0U);
+
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_ICR_REG_ADDR, UINT32_MAX);
+ seed = mmio_read_64(RCAR_CC63_BASE + CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR);
+ mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+ CC63_TRNG_SOURCE_ENABLE_REG_CLR);
+
+ node = ret = fdt_add_subnode(fdt, 0, "chosen");
+ if (ret < 0) {
+ goto err;
+ }
+
+ ret = fdt_setprop_u64(fdt, node, "kaslr-seed", seed);
+ if (ret < 0) {
+ goto err;
+ }
+
+ return;
+err:
+ NOTICE("BL2: Cannot add KASLR seed to FDT (ret=%i)\n", ret);
+ panic();
+}
+
static void bl2_add_dram_entry(uint64_t start, uint64_t size)
{
char nodename[32] = { 0 };
@@ -1215,6 +1278,9 @@
/* Print DRAM layout */
bl2_advertise_dram_size(product);
+ /* Add KASLR seed */
+ bl2_add_kaslr_seed();
+
if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
if (rcar_emmc_init() != EMMC_SUCCESS) {