You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.3 KiB
165 lines
4.3 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
|
|
* Description:KS driver in register level.
|
|
* Author: Hisilicon
|
|
* Create: 2019/06/22
|
|
*/
|
|
#include "hal_keyslot.h"
|
|
|
|
#include "osal_ext.h"
|
|
#include "drv_keyslot_define.h"
|
|
#include "drv_keyslot_func.h"
|
|
#include "hal_keyslot_reg.h"
|
|
|
|
|
|
static td_void _ks_write_reg(const td_u32 addr, const td_u32 val)
|
|
{
|
|
struct ks_mgmt *mgmt = priv_get_ks_mgmt();
|
|
|
|
reg_write((mgmt->io_base + addr), val);
|
|
ext_info_ks("ks w 0x%08x 0x%08x\n", mgmt->reg.reg + addr, val);
|
|
return;
|
|
}
|
|
|
|
td_u32 _ks_read_reg(const td_u32 addr)
|
|
{
|
|
td_u32 val = 0;
|
|
struct ks_mgmt *mgmt = priv_get_ks_mgmt();
|
|
|
|
reg_read((mgmt->io_base + addr), val);
|
|
ext_info_ks("ks r 0x%08x 0x%08x\n", mgmt->reg.reg + addr, val);
|
|
return val;
|
|
}
|
|
|
|
static td_u32 _ks_get_flush_status(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
return _ks_read_reg(KC_REE_FLUSH_BUSY);
|
|
#else
|
|
return _ks_read_reg(KC_TEE_FLUSH_BUSY);
|
|
#endif
|
|
}
|
|
|
|
static td_bool _ks_is_busy(td_void)
|
|
{
|
|
/* bit 0 is 1 means there is a key slot flushed by the current cpu */
|
|
return ((_ks_get_flush_status() & 0x1) != 0x0) ? TD_TRUE : TD_FALSE;
|
|
}
|
|
|
|
static td_bool _ks_flush_failed(td_void)
|
|
{
|
|
/* bit 1 is 1 means current cpu flush the target key slot due to time out */
|
|
return ((_ks_get_flush_status() & 0x2) != 0x0) ? TD_TRUE : TD_FALSE;
|
|
}
|
|
|
|
#define LOOP_MAX 1000
|
|
#define DELAY_US 1
|
|
|
|
static td_s32 _ks_flush_wait(td_void)
|
|
{
|
|
td_u32 time_out = LOOP_MAX;
|
|
|
|
while (time_out--) {
|
|
if (_ks_is_busy() == TD_FALSE) {
|
|
break;
|
|
}
|
|
osal_udelay(DELAY_US);
|
|
}
|
|
if (time_out == 0) {
|
|
return SOC_ERR_KS_STAT_TIME_OUT;
|
|
}
|
|
if (_ks_flush_failed()) {
|
|
return SOC_ERR_KS_FLUSH_TIME_OUT;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_bool _ks_is_tscipher(const ext_keyslot_type slot_ind)
|
|
{
|
|
if (slot_ind == EXT_KEYSLOT_TYPE_TSCIPHER) {
|
|
return TD_TRUE;
|
|
} else {
|
|
return TD_FALSE;
|
|
}
|
|
}
|
|
|
|
ks_slot_stat hal_ks_status(const ext_keyslot_type slot_ind, const td_u32 slot_num)
|
|
{
|
|
kc_rd_lock_status stat;
|
|
kc_rd_slot_num slot;
|
|
|
|
slot.u32 = _ks_read_reg(KC_RD_SLOT_NUM);
|
|
slot.bits.tscipher_slot_ind = _ks_is_tscipher(slot_ind);
|
|
slot.bits.slot_num_cfg = slot_num;
|
|
_ks_write_reg(KC_RD_SLOT_NUM, slot.u32);
|
|
|
|
stat.u32 = _ks_read_reg(KC_RD_LOCK_STATUS);
|
|
return (ks_slot_stat)stat.bits.rd_lock_status;
|
|
}
|
|
|
|
td_s32 hal_ks_lock(const ext_keyslot_type slot_ind, const td_u32 slot_num)
|
|
{
|
|
ks_slot_stat state;
|
|
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
kc_ree_lock_cmd ree_reg;
|
|
if (_ks_is_busy()) {
|
|
return SOC_ERR_KS_BUSY;
|
|
}
|
|
ree_reg.u32 = _ks_read_reg(KC_REE_LOCK_CMD);
|
|
ree_reg.bits.ree_lock_cmd = 1;
|
|
ree_reg.bits.ree_tscipher_ind = _ks_is_tscipher(slot_ind);
|
|
ree_reg.bits.ree_key_slot_num = slot_num;
|
|
_ks_write_reg(KC_REE_LOCK_CMD, ree_reg.u32);
|
|
|
|
state = hal_ks_status(slot_ind, slot_num);
|
|
if (state != KS_STAT_REE_LOCK) {
|
|
return SOC_ERR_KS_LOCKED_CPUX + state;
|
|
}
|
|
#else
|
|
kc_tee_lock_cmd tee_reg;
|
|
if (_ks_is_busy()) {
|
|
return SOC_ERR_KS_BUSY;
|
|
}
|
|
tee_reg.u32 = _ks_read_reg(KC_TEE_LOCK_CMD);
|
|
tee_reg.bits.tee_lock_cmd = 1;
|
|
tee_reg.bits.tpp_key_enable = 1;
|
|
tee_reg.bits.tee_tscipher_ind = _ks_is_tscipher(slot_ind);
|
|
tee_reg.bits.tee_key_slot_num = slot_num;
|
|
_ks_write_reg(KC_TEE_LOCK_CMD, tee_reg.u32);
|
|
|
|
state = hal_ks_status(slot_ind, slot_num);
|
|
if (state != KS_STAT_TEE_LOCK) {
|
|
return SOC_ERR_KS_LOCKED_CPUX + state;
|
|
}
|
|
#endif
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 hal_ks_unlock(const ext_keyslot_type slot_ind, const td_u32 slot_num)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
kc_ree_lock_cmd ree_reg;
|
|
if (_ks_is_busy()) {
|
|
return SOC_ERR_KS_BUSY;
|
|
}
|
|
ree_reg.u32 = _ks_read_reg(KC_REE_LOCK_CMD);
|
|
ree_reg.bits.ree_lock_cmd = 0;
|
|
ree_reg.bits.ree_tscipher_ind = _ks_is_tscipher(slot_ind);
|
|
ree_reg.bits.ree_key_slot_num = slot_num;
|
|
_ks_write_reg(KC_REE_LOCK_CMD, ree_reg.u32);
|
|
#else
|
|
kc_tee_lock_cmd tee_reg;
|
|
if (_ks_is_busy()) {
|
|
return SOC_ERR_KS_BUSY;
|
|
}
|
|
tee_reg.u32 = _ks_read_reg(KC_TEE_LOCK_CMD);
|
|
tee_reg.bits.tee_lock_cmd = 0;
|
|
tee_reg.bits.tee_tscipher_ind = _ks_is_tscipher(slot_ind);
|
|
tee_reg.bits.tee_key_slot_num = slot_num;
|
|
_ks_write_reg(KC_TEE_LOCK_CMD, tee_reg.u32);
|
|
#endif
|
|
return _ks_flush_wait();
|
|
}
|
|
|