blob: 3578b0f3e67f67653bf595387e92f45de28c6a49 [file] [log] [blame]
/*
* Copyright (C) 2014-2017 Amlogic, Inc. All rights reserved.
*
* All information contained herein is Amlogic confidential.
*
* This software is provided to you pursuant to Software License Agreement
* (SLA) with Amlogic Inc ("Amlogic"). This software may be used
* only in accordance with the terms of this agreement.
*
* Redistribution and use in source and binary forms, with or without
* modification is strictly prohibited without prior written permission from
* Amlogic.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <common.h>
#include <asm/arch/bl31_apis.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)
{
register uint32_t x0 asm("x0") = FUNCID_ANTIROLLBACK_VERSION_CHECK;
register uint32_t x1 asm("x1") = type;
register uint32_t x2 asm("x2") = version;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
__asmeq("%2", "x1")
__asmeq("%3", "x2")
"smc #0\n"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2));
} while (0);
return x0;
}
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)
{
register uint32_t x0 asm("x0") = FUNCID_AVB_VERSION_SET;
register uint32_t x1 asm("x1") = index;
register uint32_t x2 asm("x2") = version;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
__asmeq("%2", "x1")
__asmeq("%3", "x2")
"smc #0\n"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2));
} while (0);
return 0 == x0;
}
bool get_avb_antirollback(uint32_t index, uint32_t* version)
{
register uint32_t x0 asm("x0") = FUNCID_AVB_VERSION_GET;
register uint32_t x1 asm("x1") = index;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x0")
__asmeq("%3", "x1")
"smc #0\n"
: "=r"(x0), "=r"(x1)
: "r"(x0), "r"(x1));
} while (0);
if (0 == x0)
*version = x1;
return 0 == x0;
}
bool get_avb_lock_state(uint32_t* lock_state)
{
register uint32_t x0 asm("x0") = FUNCID_AVB_LOCK_STATE_GET;
register uint32_t x1 asm("x1") = 0;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x0")
"smc #0\n"
: "=r"(x0), "=r"(x1)
: "r"(x0));
} while (0);
if (0 == x0)
*lock_state = x1;
return 0 == x0;
}
bool avb_lock(void)
{
register uint32_t x0 asm("x0") = FUNCID_AVB_LOCK;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
"smc #0\n"
: "=r"(x0)
: "r"(x0));
} while (0);
return 0 == x0;
}
bool avb_unlock(void)
{
register uint32_t x0 asm("x0") = FUNCID_AVB_UNLOCK;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
"smc #0\n"
: "=r"(x0)
: "r"(x0));
} while (0);
return 0 == x0;
}