// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2015, Linaro Limited */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PLAT_HW_UNIQUE_KEY_LENGTH 32 static struct serial8250_uart_data console_data; static uint8_t plat_huk[PLAT_HW_UNIQUE_KEY_LENGTH]; register_phys_mem(MEM_AREA_RAM_SEC, TZDRAM_BASE, TEE_RAM_VA_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_SEC, SECRAM_BASE, SECRAM_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICC_BASE, GICC_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICD_BASE, GICD_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, SERIAL8250_UART_REG_SIZE); void boot_primary_init_intc(void) { gic_init(GICC_BASE, GICD_BASE); } void boot_secondary_init_intc(void) { gic_init_per_cpu(); } struct plat_nsec_ctx { uint32_t usr_sp; uint32_t usr_lr; uint32_t svc_sp; uint32_t svc_lr; uint32_t svc_spsr; uint32_t abt_sp; uint32_t abt_lr; uint32_t abt_spsr; uint32_t und_sp; uint32_t und_lr; uint32_t und_spsr; uint32_t irq_sp; uint32_t irq_lr; uint32_t irq_spsr; uint32_t fiq_sp; uint32_t fiq_lr; uint32_t fiq_spsr; uint32_t fiq_rx[5]; uint32_t mon_lr; uint32_t mon_spsr; }; struct plat_boot_args { struct plat_nsec_ctx nsec_ctx; uint8_t huk[PLAT_HW_UNIQUE_KEY_LENGTH]; }; void init_sec_mon(unsigned long nsec_entry) { struct plat_boot_args *plat_boot_args; struct sm_nsec_ctx *nsec_ctx; plat_boot_args = phys_to_virt(nsec_entry, MEM_AREA_IO_SEC, 1); if (!plat_boot_args) panic(); /* Invalidate cache to fetch data from external memory */ cache_op_inner(DCACHE_AREA_INVALIDATE, plat_boot_args, sizeof(*plat_boot_args)); /* Initialize secure monitor */ nsec_ctx = sm_get_nsec_ctx(); nsec_ctx->ub_regs.usr_sp = plat_boot_args->nsec_ctx.usr_sp; nsec_ctx->ub_regs.usr_lr = plat_boot_args->nsec_ctx.usr_lr; nsec_ctx->ub_regs.irq_spsr = plat_boot_args->nsec_ctx.irq_spsr; nsec_ctx->ub_regs.irq_sp = plat_boot_args->nsec_ctx.irq_sp; nsec_ctx->ub_regs.irq_lr = plat_boot_args->nsec_ctx.irq_lr; nsec_ctx->ub_regs.svc_spsr = plat_boot_args->nsec_ctx.svc_spsr; nsec_ctx->ub_regs.svc_sp = plat_boot_args->nsec_ctx.svc_sp; nsec_ctx->ub_regs.svc_lr = plat_boot_args->nsec_ctx.svc_lr; nsec_ctx->ub_regs.abt_spsr = plat_boot_args->nsec_ctx.abt_spsr; nsec_ctx->ub_regs.abt_sp = plat_boot_args->nsec_ctx.abt_sp; nsec_ctx->ub_regs.abt_lr = plat_boot_args->nsec_ctx.abt_lr; nsec_ctx->ub_regs.und_spsr = plat_boot_args->nsec_ctx.und_spsr; nsec_ctx->ub_regs.und_sp = plat_boot_args->nsec_ctx.und_sp; nsec_ctx->ub_regs.und_lr = plat_boot_args->nsec_ctx.und_lr; nsec_ctx->mon_lr = plat_boot_args->nsec_ctx.mon_lr; nsec_ctx->mon_spsr = plat_boot_args->nsec_ctx.mon_spsr; memcpy(plat_huk, plat_boot_args->huk, sizeof(plat_boot_args->huk)); } void plat_console_init(void) { serial8250_uart_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); register_serial_console(&console_data.chip); } #if defined(CFG_OTP_SUPPORT) TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) { memcpy(&hwkey->data[0], &plat_huk[0], sizeof(hwkey->data)); return TEE_SUCCESS; } #endif