// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2019 Amlogic, Inc. All rights reserved. */ #include #include #include #include #include #ifndef DEBUG_NOCS_SEB #define DEBUG_NOCS_SEB 0 #endif #define debug_print(fmt, args...) \ debug_cond(DEBUG_NOCS_SEB, fmt, ##args) #ifdef CONFIG_UPDATE_UBOOT_NOCS static unsigned int array_to_uint32_little(unsigned char *array) { return ((array)[3] << 24 | (array)[2] << 16 | (array)[1] << 8 | (array)[0]); } #endif nocs_seb_status get_nocs_inf(nocs_chip_type *chip_type, nocs_scs_status *scs_status) { #ifdef CONFIG_UPDATE_UBOOT_NOCS unsigned int reg_value = 0; int soc_family_id = 0; soc_family_id = get_cpu_id().family_id; debug_print("family_id:0x%x\n", soc_family_id); if (soc_family_id != MESON_CPU_MAJOR_ID_SC2) { *chip_type = NOCS_UNDEFINE; *scs_status = NOCS_SCS_DISABLE; return SEB_NO_ERROR; } reg_value = readl(CA_NOCS_MODE_REG); debug_print("reg_value0:0x%x\n", reg_value); if ((reg_value & 0x0f) == CA_NOCS_MODE) { *chip_type = NOCS_S905C2_TYPE1; reg_value = readl(CA_NOCS_SCS_STATUS); debug_print("reg_value1:0x%x\n", reg_value); if ((reg_value & CA_NOCS_SCS) != 0) *scs_status = NOCS_SCS_ENABLE; else *scs_status = NOCS_SCS_DISABLE; } else { *chip_type = NOCS_UNDEFINE; *scs_status = NOCS_SCS_DISABLE; } debug_print("chiptype:%d scs_status:%d\n", *chip_type, *scs_status); #else *chip_type = NOCS_UNDEFINE; *scs_status = NOCS_SCS_DISABLE; debug_print("UnConfig chiptype:%d scs_status:%d\n", *chip_type, *scs_status); #endif return SEB_NO_ERROR; } nocs_seb_status nocs_secure_boot_modify(nocs_chip_type chip_type, unsigned char *flash_boot, unsigned int flash_boot_size, unsigned char *update_boot, unsigned int update_boot_size, nocs_boot_replace *nocs_replace) { int ret = SEB_NO_ERROR; #ifdef CONFIG_UPDATE_UBOOT_NOCS unsigned int i; switch (chip_type) { case NOCS_S905C2_TYPE1: { for (i = 0; i < CMP_SIZE; i++) if (flash_boot[CMP_OFFSET_TYPE1 + i] != update_boot[CMP_OFFSET_TYPE1 + i]) { ret = SEB_UNSUPPORT; break; } nocs_replace->area_num = 2; nocs_replace->offset[0] = REPLACE_INFO_OFFSET; nocs_replace->size[0] = REPLACE_INFO_SIZE; nocs_replace->offset[1] = array_to_uint32_little(&update_boot[INFO_OFFSET]); nocs_replace->size[1] = array_to_uint32_little(&update_boot[INFO_OFFSET + 4]); } break; default: { printf("Unsupport chip type!\n"); ret = SEB_ERROR; } break; } #else nocs_replace->area_num = 0; #endif return ret; } #if DEBUG_NOCS_SEB static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { nocs_chip_type chip_type; nocs_scs_status scs_status; nocs_seb_status ret; ret = get_nocs_inf(&chip_type, &scs_status); debug_print("test chiptype:%d scs_status:%d ret:%d\n", chip_type, scs_status, ret); return 0; } U_BOOT_CMD(dnocs, 1, 0, do_test, "determines whether NOCS are included", "read chip id and cas mode to determines whether NOCS are included\n" ); #endif