/* * Copyright 2020 HabanaLabs, Ltd. * All Rights Reserved.
*/
#include"habanalabs.h"
staticconstchar * const hl_glbl_error_cause[] = { "Error due to un-priv read", "Error due to un-secure read", "Error due to read from unmapped reg", "Error due to un-priv write", "Error due to un-secure write", "Error due to write to unmapped reg", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "External I/F write sec violation", "External I/F write to un-mapped reg", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "Read to write only", "Write to read only"
};
/** * hl_get_pb_block - return the relevant block within the block array * * @hdev: pointer to hl_device structure * @mm_reg_addr: register address in the desired block * @pb_blocks: blocks array * @array_size: blocks array size *
*/ staticint hl_get_pb_block(struct hl_device *hdev, u32 mm_reg_addr, const u32 pb_blocks[], int array_size)
{ int i;
u32 start_addr, end_addr;
for (i = 0 ; i < array_size ; i++) {
start_addr = pb_blocks[i];
end_addr = start_addr + HL_BLOCK_SIZE;
dev_err(hdev->dev, "No protection domain was found for 0x%x\n",
mm_reg_addr); return -EDOM;
}
/** * hl_unset_pb_in_block - clear a specific protection bit in a block * * @hdev: pointer to hl_device structure * @reg_offset: register offset will be converted to bit offset in pb block * @sgs_entry: pb array *
*/ staticint hl_unset_pb_in_block(struct hl_device *hdev, u32 reg_offset, struct hl_block_glbl_sec *sgs_entry)
{ if ((reg_offset >= HL_BLOCK_SIZE) || (reg_offset & 0x3)) {
dev_err(hdev->dev, "Register offset(%d) is out of range(%d) or invalid\n",
reg_offset, HL_BLOCK_SIZE); return -EINVAL;
}
/** * hl_secure_block - locally memsets a block to 0 * * @hdev: pointer to hl_device structure * @sgs_array: pb array to clear * @array_size: blocks array size *
*/ void hl_secure_block(struct hl_device *hdev, struct hl_block_glbl_sec sgs_array[], int array_size)
{ int i;
for (i = 0 ; i < array_size ; i++)
memset((char *)(sgs_array[i].sec_array), 0,
HL_BLOCK_GLBL_SEC_SIZE);
}
/** * hl_init_pb_with_mask - set selected pb instances with mask in HW according * to given configuration * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_array: unsecured register array * @user_regs_array_size: unsecured register array size * @mask: enabled instances mask: 1- enabled, 0- disabled
*/ int hl_init_pb_with_mask(struct hl_device *hdev, u32 num_dcores,
u32 dcore_offset, u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, const u32 *user_regs_array, u32 user_regs_array_size, u64 mask)
{ int i, j; struct hl_block_glbl_sec *glbl_sec;
glbl_sec = kcalloc(blocks_array_size, sizeof(struct hl_block_glbl_sec),
GFP_KERNEL); if (!glbl_sec) return -ENOMEM;
/* Fill all blocks with the same configuration */ for (i = 0 ; i < num_dcores ; i++) { for (j = 0 ; j < num_instances ; j++) { int seq = i * num_instances + j;
/** * hl_init_pb - set pb in HW according to given configuration * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_array: unsecured register array * @user_regs_array_size: unsecured register array size *
*/ int hl_init_pb(struct hl_device *hdev, u32 num_dcores, u32 dcore_offset,
u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, const u32 *user_regs_array, u32 user_regs_array_size)
{ return hl_init_pb_with_mask(hdev, num_dcores, dcore_offset,
num_instances, instance_offset, pb_blocks,
blocks_array_size, user_regs_array,
user_regs_array_size, ULLONG_MAX);
}
/** * hl_init_pb_ranges_with_mask - set pb instances using mask in HW according to * given configuration unsecurring registers * ranges instead of specific registers * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_range_array: unsecured register range array * @user_regs_range_array_size: unsecured register range array size * @mask: enabled instances mask: 1- enabled, 0- disabled
*/ int hl_init_pb_ranges_with_mask(struct hl_device *hdev, u32 num_dcores,
u32 dcore_offset, u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, conststruct range *user_regs_range_array,
u32 user_regs_range_array_size, u64 mask)
{ int i, j, rc = 0; struct hl_block_glbl_sec *glbl_sec;
glbl_sec = kcalloc(blocks_array_size, sizeof(struct hl_block_glbl_sec),
GFP_KERNEL); if (!glbl_sec) return -ENOMEM;
/* Fill all blocks with the same configuration */ for (i = 0 ; i < num_dcores ; i++) { for (j = 0 ; j < num_instances ; j++) { int seq = i * num_instances + j;
/** * hl_init_pb_ranges - set pb in HW according to given configuration unsecurring * registers ranges instead of specific registers * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_range_array: unsecured register range array * @user_regs_range_array_size: unsecured register range array size *
*/ int hl_init_pb_ranges(struct hl_device *hdev, u32 num_dcores,
u32 dcore_offset, u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, conststruct range *user_regs_range_array,
u32 user_regs_range_array_size)
{ return hl_init_pb_ranges_with_mask(hdev, num_dcores, dcore_offset,
num_instances, instance_offset, pb_blocks,
blocks_array_size, user_regs_range_array,
user_regs_range_array_size, ULLONG_MAX);
}
/** * hl_init_pb_single_dcore - set pb for a single docre in HW * according to given configuration * * @hdev: pointer to hl_device structure * @dcore_offset: offset from the dcore0 * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_array: unsecured register array * @user_regs_array_size: unsecured register array size *
*/ int hl_init_pb_single_dcore(struct hl_device *hdev, u32 dcore_offset,
u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, const u32 *user_regs_array, u32 user_regs_array_size)
{ int i, rc = 0; struct hl_block_glbl_sec *glbl_sec;
glbl_sec = kcalloc(blocks_array_size, sizeof(struct hl_block_glbl_sec),
GFP_KERNEL); if (!glbl_sec) return -ENOMEM;
/* Fill all blocks with the same configuration */ for (i = 0 ; i < num_instances ; i++)
hl_config_glbl_sec(hdev, pb_blocks, glbl_sec,
dcore_offset + i * instance_offset,
blocks_array_size);
free_glbl_sec:
kfree(glbl_sec);
return rc;
}
/** * hl_init_pb_ranges_single_dcore - set pb for a single docre in HW according * to given configuration unsecurring * registers ranges instead of specific * registers * * @hdev: pointer to hl_device structure * @dcore_offset: offset from the dcore0 * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @user_regs_range_array: unsecured register range array * @user_regs_range_array_size: unsecured register range array size *
*/ int hl_init_pb_ranges_single_dcore(struct hl_device *hdev, u32 dcore_offset,
u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, conststruct range *user_regs_range_array, u32 user_regs_range_array_size)
{ int i; struct hl_block_glbl_sec *glbl_sec;
glbl_sec = kcalloc(blocks_array_size, sizeof(struct hl_block_glbl_sec),
GFP_KERNEL); if (!glbl_sec) return -ENOMEM;
/* Fill all blocks with the same configuration */ for (i = 0 ; i < num_instances ; i++)
hl_config_glbl_sec(hdev, pb_blocks, glbl_sec,
dcore_offset + i * instance_offset,
blocks_array_size);
kfree(glbl_sec);
return 0;
}
/** * hl_ack_pb_with_mask - ack pb with mask in HW according to given configuration * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size * @mask: enabled instances mask: 1- enabled, 0- disabled *
*/ void hl_ack_pb_with_mask(struct hl_device *hdev, u32 num_dcores,
u32 dcore_offset, u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size, u64 mask)
{ int i, j;
/* ack all blocks */ for (i = 0 ; i < num_dcores ; i++) { for (j = 0 ; j < num_instances ; j++) { int seq = i * num_instances + j;
/** * hl_ack_pb - ack pb in HW according to given configuration * * @hdev: pointer to hl_device structure * @num_dcores: number of decores to apply configuration to * set to HL_PB_SHARED if need to apply only once * @dcore_offset: offset between dcores * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size *
*/ void hl_ack_pb(struct hl_device *hdev, u32 num_dcores, u32 dcore_offset,
u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size)
{
hl_ack_pb_with_mask(hdev, num_dcores, dcore_offset, num_instances,
instance_offset, pb_blocks, blocks_array_size,
ULLONG_MAX);
}
/** * hl_ack_pb_single_dcore - ack pb for single docre in HW * according to given configuration * * @hdev: pointer to hl_device structure * @dcore_offset: offset from dcore0 * @num_instances: number of instances to apply configuration to * @instance_offset: offset between instances * @pb_blocks: blocks array * @blocks_array_size: blocks array size *
*/ void hl_ack_pb_single_dcore(struct hl_device *hdev, u32 dcore_offset,
u32 num_instances, u32 instance_offset, const u32 pb_blocks[], u32 blocks_array_size)
{ int i;
/* ack all blocks */ for (i = 0 ; i < num_instances ; i++)
hl_ack_pb_security_violations(hdev, pb_blocks,
dcore_offset + i * instance_offset,
blocks_array_size);
/* Calculation above returns an address for FW use, and therefore should * be casted for driver use.
*/ return (fw_block_base_address - lower_32_bits(prop->cfg_base_address));
}
staticbool hl_check_block_type_exclusion(struct hl_skip_blocks_cfg *skip_blocks_cfg, int block_type)
{ int i;
/* Check if block type is listed in the exclusion list of block types */ for (i = 0 ; i < skip_blocks_cfg->block_types_len ; i++) if (block_type == skip_blocks_cfg->block_types[i]) returntrue;
sub_minor++;
} while (sub_minor < block_info_arr->sub_minor);
minor++;
} while (minor < block_info_arr->minor);
}
}
return 0;
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.30Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.