121 lines
2.7 KiB
C
121 lines
2.7 KiB
C
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
|
/*
|
|
* common/anti-rollback.c
|
|
*
|
|
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/arch/bl31_apis.h>
|
|
#include <linux/arm-smccc.h>
|
|
#include "anti-rollback.h"
|
|
|
|
#define FUNCID_ANTIROLLBACK_VERSION_CHECK 0xb2000010
|
|
|
|
#define FUNCID_AVB_VERSION_SET 0xb2000011
|
|
#define FUNCID_AVB_VERSION_GET 0xb2000012
|
|
#define FUNCID_AVB_LOCK_STATE_GET 0xb2000013
|
|
#define FUNCID_AVB_LOCK 0xb2000014
|
|
#define FUNCID_AVB_UNLOCK 0xb2000015
|
|
|
|
#define IMAGE_VERSION_TYPE_BOOTLOADER 0x001
|
|
#define IMAGE_VERSION_TYPE_RECOVERY 0x002
|
|
#define IMAGE_VERSION_TYPE_BOOT 0x003
|
|
|
|
#define KERNEL_TYPE_UNKNOWN 0x00
|
|
#define KERNEL_TYPE_BOOT 0x01
|
|
#define KERNEL_TYPE_RECOVERY 0x02
|
|
|
|
static uint32_t antirollback_image_version_check(uint32_t type,
|
|
uint32_t version)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_ANTIROLLBACK_VERSION_CHECK, type, version, 0, 0, 0, 0, 0, &res);
|
|
|
|
return res.a0;
|
|
}
|
|
|
|
bool check_antirollback(uint32_t kernel_version)
|
|
{
|
|
bool ret = true;
|
|
uint32_t type = (kernel_version >> 24);
|
|
uint32_t version = ((kernel_version << 8) >> 8);
|
|
if (KERNEL_TYPE_BOOT == type) {
|
|
if (antirollback_image_version_check(IMAGE_VERSION_TYPE_BOOT,
|
|
version) != 0) {
|
|
printf("checking boot.img version failed\n");
|
|
ret = false;
|
|
}
|
|
}
|
|
else if (KERNEL_TYPE_RECOVERY == type) {
|
|
if (antirollback_image_version_check(
|
|
IMAGE_VERSION_TYPE_RECOVERY,
|
|
version) != 0) {
|
|
printf("checking recovery.img version failed\n");
|
|
ret = false;
|
|
}
|
|
}
|
|
else {
|
|
printf("the kernel type is unknown\n");
|
|
ret = false;
|
|
}
|
|
|
|
if (ret)
|
|
printf("checking version success\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool set_avb_antirollback(uint32_t index, uint32_t version)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_AVB_VERSION_SET, index, version, 0, 0, 0, 0, 0, &res);
|
|
|
|
return res.a0 == 0;
|
|
}
|
|
|
|
bool get_avb_antirollback(uint32_t index, uint32_t* version)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_AVB_VERSION_GET, index, 0, 0, 0, 0, 0, 0, &res);
|
|
|
|
if (res.a0 == 0)
|
|
*version = res.a1;
|
|
|
|
return res.a0 == 0;
|
|
}
|
|
|
|
bool get_avb_lock_state(uint32_t* lock_state)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_AVB_LOCK_STATE_GET, 0, 0, 0, 0, 0, 0, 0, &res);
|
|
|
|
if (res.a0 == 0)
|
|
*lock_state = res.a1;
|
|
|
|
return res.a0 == 0;
|
|
}
|
|
|
|
bool avb_lock(void)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_AVB_LOCK, 0, 0, 0, 0, 0, 0, 0, &res);
|
|
|
|
return res.a0 == 0;
|
|
}
|
|
|
|
bool avb_unlock(void)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(FUNCID_AVB_UNLOCK, 0, 0, 0, 0, 0, 0, 0, &res);
|
|
|
|
return res.a0 == 0;
|
|
}
|