static int vmpu_sanity_checks(void) { /* Verify the uVisor configuration structure. */ if (__uvisor_config.magic != UVISOR_MAGIC) { HALT_ERROR(SANITY_CHECK_FAILED, "config magic mismatch: &0x%08X = 0x%08X - exptected 0x%08X\n", &__uvisor_config, __uvisor_config.magic, UVISOR_MAGIC); } /* Verify basic assumptions about vmpu_bits/__builtin_clz. */ assert(__builtin_clz(0) == 32); assert(__builtin_clz(1UL << 31) == 0); assert(vmpu_bits(0) == 0); assert(vmpu_bits(1UL << 31) == 32); assert(vmpu_bits(0x8000UL) == 16); assert(vmpu_bits(0x8001UL) == 16); assert(vmpu_bits(1) == 1); /* Verify that the core version is the same as expected. */ if (!CORE_VERSION_CHECK() || !CORE_REVISION_CHECK()) { HALT_ERROR(SANITY_CHECK_FAILED, "This core is unsupported or there is a mismatch between the uVisor " "configuration you are using and the core this configuration supports.\n\r"); } /* Verify that the known hard-coded symbols are equal to the ones taken from * the host linker script. */ assert((uint32_t) __uvisor_config.flash_start == FLASH_ORIGIN); assert((uint32_t) __uvisor_config.sram_start == SRAM_ORIGIN); /* Verify that the uVisor binary blob is positioned at the flash offset. */ assert(((uint32_t) __uvisor_config.flash_start + FLASH_OFFSET) == (uint32_t) __uvisor_config.main_start); /* Verify that the uVisor mode configuration is inside the public flash. */ assert(vmpu_public_flash_addr((uint32_t) __uvisor_config.mode)); assert(*(__uvisor_config.mode) <= 2); DPRINTF("uVisor mode: %u\n", *(__uvisor_config.mode)); /* Verify the SRAM relocation. */ /* Note: SRAM_ORIGIN + SRAM_OFFSET is assumed to be aligned to 32 bytes. */ assert((uint32_t) __uvisor_config.bss_start == (SRAM_ORIGIN + SRAM_OFFSET)); DPRINTF("uvisor_ram : @0x%08X (%u bytes) [config]\n", __uvisor_config.bss_main_start, VMPU_REGION_SIZE(__uvisor_config.bss_main_start, __uvisor_config.bss_main_end)); DPRINTF(" @0x%08X (%u bytes) [linker]\n", SRAM_ORIGIN + SRAM_OFFSET, UVISOR_SRAM_LENGTH_USED); /* Verify that the sections inside the BSS region are disjoint. */ DPRINTF("bss_boxes : @0x%08X (%u bytes) [config]\n", __uvisor_config.bss_boxes_start, VMPU_REGION_SIZE(__uvisor_config.bss_boxes_start, __uvisor_config.bss_boxes_end)); assert(__uvisor_config.bss_end > __uvisor_config.bss_start); assert(__uvisor_config.bss_main_end > __uvisor_config.bss_main_start); assert(__uvisor_config.bss_boxes_end > __uvisor_config.bss_boxes_start); assert((__uvisor_config.bss_main_start >= __uvisor_config.bss_boxes_end) || (__uvisor_config.bss_main_end <= __uvisor_config.bss_boxes_start)); /* Verify the uVisor expectations regarding its own memories. */ assert(VMPU_REGION_SIZE(__uvisor_config.bss_main_start, __uvisor_config.bss_main_end) == UVISOR_SRAM_LENGTH_USED); assert((uint32_t) __uvisor_config.bss_main_end == (SRAM_ORIGIN + SRAM_OFFSET + UVISOR_SRAM_LENGTH_USED)); assert((uint32_t) __uvisor_config.bss_main_end == (SRAM_ORIGIN + UVISOR_SRAM_LENGTH_PROTECTED)); /* Verify SRAM sections are within uVisor's own SRAM. */ assert(&__bss_start__ >= __uvisor_config.bss_main_start); assert(&__bss_end__ <= __uvisor_config.bss_main_end); assert(&__data_start__ >= __uvisor_config.bss_main_start); assert(&__data_end__ <= __uvisor_config.bss_main_end); assert(&__stack_start__ >= __uvisor_config.bss_main_start); assert(&__stack_end__ <= __uvisor_config.bss_main_end); /* Verify that the secure flash area is accessible and after public code. */ assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.secure_start)); assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.secure_end)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.secure_start)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.secure_end)); assert(__uvisor_config.secure_start <= __uvisor_config.secure_end); assert(__uvisor_config.secure_start >= __uvisor_config.main_end); /* Verify the configuration table. */ assert(__uvisor_config.cfgtbl_ptr_start <= __uvisor_config.cfgtbl_ptr_end); assert(__uvisor_config.cfgtbl_ptr_start >= __uvisor_config.secure_start); assert(__uvisor_config.cfgtbl_ptr_end <= __uvisor_config.secure_end); assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.cfgtbl_ptr_start)); assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.cfgtbl_ptr_end)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.cfgtbl_ptr_start)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.cfgtbl_ptr_end)); /* Verify the register gateway pointers section. */ assert(__uvisor_config.register_gateway_ptr_start <= __uvisor_config.register_gateway_ptr_end); assert(__uvisor_config.register_gateway_ptr_start >= __uvisor_config.secure_start); assert(__uvisor_config.register_gateway_ptr_end <= __uvisor_config.secure_end); assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.register_gateway_ptr_start)); assert(!vmpu_public_flash_addr((uint32_t) __uvisor_config.register_gateway_ptr_end)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.register_gateway_ptr_start)); assert(vmpu_flash_addr((uint32_t) __uvisor_config.register_gateway_ptr_end)); /* Verify that every register gateway in memory is aligned to 4 bytes. */ uint32_t * register_gateway = __uvisor_config.register_gateway_ptr_start; for (; register_gateway < __uvisor_config.register_gateway_ptr_end; register_gateway++) { if (*register_gateway & 0x3) { HALT_ERROR(SANITY_CHECK_FAILED, "Register gateway 0x%08X is not aligned to 4 bytes", (uint32_t) register_gateway); } } /* Return an error if uVisor is disabled. */ if (!__uvisor_config.mode || (*__uvisor_config.mode == 0)) { return -1; } else { return 0; } }
static int vmpu_sanity_checks(void) { /* verify uvisor config structure */ if(__uvisor_config.magic != UVISOR_MAGIC) HALT_ERROR(SANITY_CHECK_FAILED, "config magic mismatch: &0x%08X = 0x%08X \ - exptected 0x%08X\n", &__uvisor_config, __uvisor_config.magic, UVISOR_MAGIC); /* verify basic assumptions about vmpu_bits/__builtin_clz */ assert(__builtin_clz(0) == 32); assert(__builtin_clz(1UL << 31) == 0); assert(vmpu_bits(0) == 0); assert(vmpu_bits(1UL << 31) == 32); assert(vmpu_bits(0x8000UL) == 16); assert(vmpu_bits(0x8001UL) == 16); assert(vmpu_bits(1) == 1); /* verify that __uvisor_config is within valid flash */ assert( ((uint32_t) &__uvisor_config) >= FLASH_ORIGIN ); assert( ((((uint32_t) &__uvisor_config) + sizeof(__uvisor_config)) <= (FLASH_ORIGIN + FLASH_LENGTH)) ); /* verify if configuration mode is inside flash memory */ assert((uint32_t)__uvisor_config.mode >= FLASH_ORIGIN); assert((uint32_t)__uvisor_config.mode <= (FLASH_ORIGIN + FLASH_LENGTH - 4)); DPRINTF("uvisor_mode: %u\n", *__uvisor_config.mode); assert(*__uvisor_config.mode <= 2); /* verify SRAM relocation */ DPRINTF("uvisor_ram : @0x%08X (%u bytes) [config]\n", __uvisor_config.bss_main_start, VMPU_REGION_SIZE(__uvisor_config.bss_main_start, __uvisor_config.bss_main_end)); DPRINTF(" (0x%08X (%u bytes) [linker]\n", RESERVED_SRAM_START, USE_SRAM_SIZE); assert( __uvisor_config.bss_main_end > __uvisor_config.bss_main_start ); assert( VMPU_REGION_SIZE(__uvisor_config.bss_main_start, __uvisor_config.bss_main_end) == USE_SRAM_SIZE ); assert(&__stack_end__ <= __uvisor_config.bss_main_end); assert( (uint32_t) __uvisor_config.bss_main_start == RESERVED_SRAM_START); assert( (uint32_t) __uvisor_config.bss_main_end == (RESERVED_SRAM_START + USE_SRAM_SIZE) ); /* verify that secure flash area is accessible and after public code */ assert( __uvisor_config.secure_start <= __uvisor_config.secure_end ); assert( (uint32_t) __uvisor_config.secure_end <= (uint32_t) (FLASH_ORIGIN + FLASH_LENGTH) ); assert( (uint32_t) __uvisor_config.secure_start >= (uint32_t) &vmpu_sanity_checks ); /* verify configuration table */ assert( __uvisor_config.cfgtbl_ptr_start <= __uvisor_config.cfgtbl_ptr_end ); assert( __uvisor_config.cfgtbl_ptr_start >= __uvisor_config.secure_start ); assert( (uint32_t) __uvisor_config.cfgtbl_ptr_end <= (uint32_t) (FLASH_ORIGIN + FLASH_LENGTH) ); /* return error if uvisor is disabled */ if(!__uvisor_config.mode || (*__uvisor_config.mode == 0)) return -1; else return 0; }