This commit is contained in:
HailoRT-Automation
2022-03-29 19:08:05 +03:00
commit dd37bf9936
370 changed files with 80735 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
{
"_comment":
[
"This file defines the available fields of the firmwares config. It is not used to serialize any data.",
"WARNING! DO NOT CHANGE THE ORDER OF THE DEFINITIONS AS IT WILL CHANGE THEIR GENERATED VALUES!"
],
"version": 0,
"categories":
{
"network":
{
"entries":
{
"should_use_dhcp": {"size": 1, "deserialize_as": "bool"},
"mac_address": {"size": 1, "length": 6, "deserialize_as": "mac_address"},
"static_ip_address": {"size": 4, "deserialize_as": "ipv4"},
"static_gw_address": {"size": 4, "deserialize_as": "ipv4"},
"static_netmask": {"size": 4, "deserialize_as": "ipv4"},
"rx_pause_frames_enable": {"size": 1, "deserialize_as": "bool"}
}
},
"system":
{
"entries":
{
"name": {"size": 1, "length": 32, "deserialize_as": "str"},
"app_watchdog_enable": {"size": 1, "deserialize_as": "bool"},
"app_watchdog_cycles": {"size": 4, "deserialize_as": "int"},
"core_watchdog_enable": {"size": 1, "deserialize_as": "bool"},
"core_watchdog_cycles": {"size": 4, "deserialize_as": "int"},
"watchdog_mode" : {"size": 1, "deserialize_as": "watchdog_mode"},
"max_neural_network_core_clock_rate": {"size": 4, "deserialize_as": "clock_frequency"},
"supported_aspm_states": {"size": 1, "deserialize_as": "supported_aspm_states"},
"bus_0_i2c_speed": {"size": 1, "deserialize_as": "i2c_speed"},
"bus_1_i2c_speed": {"size": 1, "deserialize_as": "i2c_speed"},
"bus_2_i2c_speed": {"size": 1, "deserialize_as": "i2c_speed"},
"bus_3_i2c_speed": {"size": 1, "deserialize_as": "i2c_speed"},
"supported_aspm_l1_substates": {"size": 1, "deserialize_as": "supported_aspm_l1_substates"},
"overcurrent_parameters_source": {"size": 1, "deserialize_as": "overcurrent_parameters_source"},
"overcurrent_monitoring_red_threshold": {"size": 4, "deserialize_as": "int"},
"overcurrent_conversion_time_microseconds": {"size": 4, "deserialize_as": "conversion_time"},
"temperature_parameters_source": {"size": 1, "deserialize_as": "temperature_parameters_source"},
"temperature_red_threshold": {"size": 1, "deserialize_as": "int"},
"temperature_red_hysteresis_threshold": {"size": 1, "deserialize_as": "int"},
"temperature_orange_threshold": {"size": 1, "deserialize_as": "int"},
"temperature_orange_hysteresis_threshold": {"size": 1, "deserialize_as": "int"},
"temperature_throttling_enable": {"size": 1, "deserialize_as": "bool"},
"overcurrent_monitoring_orange_threshold_enable": {"size": 1, "deserialize_as": "bool"}
}
},
"control":
{
"entries":
{
"udp_port": {"size": 2, "deserialize_as": "int"}
}
},
"d2h_event":
{
"entries":
{
"host_udp_port": {"size": 2, "deserialize_as": "int"},
"src_udp_port": {"size": 2, "deserialize_as": "int"},
"host_ip_address": {"size": 4, "deserialize_as": "ipv4"},
"connection_type": {"size": 1, "deserialize_as": "bool"}
}
},
"logger":
{
"entries":
{
"send_via_pci": {"size": 1, "deserialize_as": "bool"},
"send_via_uart": {"size": 1, "deserialize_as": "bool"},
"logger_level": {"size": 4, "deserialize_as": "logger_level"}
}
}
}
}

144
common/config_schema.json Normal file
View File

@@ -0,0 +1,144 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "config_schema",
"description": "schema for user config",
"type": "object",
"properties":
{
"network":
{
"type": "object",
"properties":
{
"should_use_dhcp": {"type": "boolean"},
"mac_address": {"$ref": "#/definitions/mac_address"},
"static_ip_address": {"type": "string", "format": "ipv4"},
"static_gw_address": {"type": "string", "format": "ipv4"},
"static_netmask": {"type": "string", "format": "ipv4"},
"rx_pause_frames_enable": {"type": "boolean"}
}
},
"system":
{
"type": "object",
"properties":
{
"name": {"type": "string", "maxLength": 32},
"app_watchdog_enable": {"type": "boolean"},
"app_watchdog_cycles": {"$ref": "#/definitions/uint16_t"},
"core_watchdog_enable": {"type": "boolean"},
"core_watchdog_cycles": {"$ref": "#/definitions/uint16_t"},
"watchdog_mode" : {"$ref": "#/definitions/watchdog_mode"},
"max_neural_network_core_clock_rate": {"$ref": "#/definitions/clock_frequency"},
"supported_aspm_states": {"$ref": "#/definitions/supported_aspm_states"},
"bus_0_i2c_speed": {"$ref": "#/definitions/i2c_speed"},
"bus_1_i2c_speed": {"$ref": "#/definitions/i2c_speed"},
"bus_2_i2c_speed": {"$ref": "#/definitions/i2c_speed"},
"bus_3_i2c_speed": {"$ref": "#/definitions/i2c_speed"},
"supported_aspm_l1_substates": {"$ref": "#/definitions/supported_aspm_l1_substates"},
"overcurrent_parameters_source": {"$ref": "#/definitions/overcurrent_parameters_source"},
"overcurrent_monitoring_red_threshold": {"$ref": "#/definitions/uint32_t"},
"overcurrent_conversion_time_microseconds": {"$ref": "#/definitions/conversion_time"},
"temperature_parameters_source": {"$ref": "#/definitions/temperature_parameters_source"},
"temperature_red_threshold": {"$ref": "#/definitions/int8_t"},
"temperature_red_hysteresis_threshold": {"$ref": "#/definitions/int8_t"},
"temperature_orange_threshold": {"$ref": "#/definitions/int8_t"},
"temperature_orange_hysteresis_threshold": {"$ref": "#/definitions/int8_t"},
"overcurrent_monitoring_orange_threshold_enable": {"type": "boolean"}
}
},
"control":
{
"type": "object",
"properties":
{
"udp_port": {"$ref": "#/definitions/uint16_t"}
}
},
"d2h_event":
{
"type": "object",
"properties":
{
"host_udp_port": {"$ref": "#/definitions/uint16_t"},
"src_udp_port": {"$ref": "#/definitions/uint16_t"},
"host_ip_address": {"type": "string", "format": "ipv4"},
"connection_type": {"type": "boolean"}
}
},
"logger":
{
"type": "object",
"properties":
{
"send_via_pci": {"type": "boolean"},
"send_via_uart": {"type": "boolean"},
"logger_level": {"$ref": "#/definitions/logger_level"}
}
}
},
"definitions":
{
"mac_address":
{
"type": "string",
"pattern": "^(([0-9a-fA-F]{2}[:]){5}|([0-9a-fA-F]{2}){5})([0-9a-fA-F]{2})$"
},
"clock_frequency":
{
"enum":
["100MHZ", "200MHZ", "400MHZ"]
},
"supported_aspm_states":
{
"enum":
["ASPM_DISABLED", "ASPM_L1_ONLY", "ASPM_L0S_L1",
"ASPM DISABLED", "ASPM L1 ONLY", "ASPM L0S L1"]
},
"i2c_speed":
{
"enum":
["I2C_SPEED_STANDARD", "I2C_SPEED_FAST",
"I2C SPEED STANDARD", "I2C SPEED FAST"]
},
"supported_aspm_l1_substates":
{
"enum":
["ASPM_L1_SUBSTATES_DISABLED", "ASPM_L1_SUBSTATES_L11_ONLY", "ASPM_L1_SUBSTATES_L11_L12",
"ASPM L1 SUBSTATES DISABLED", "ASPM L1 SUBSTATES L1.1 ONLY", "ASPM L1 SUBSTATES L1.1 L1.2"]
},
"watchdog_mode":
{
"enum":
["WD_MODE_HW_SW", "WD_MODE_HW_ONLY",
"WD MODE HW SW", "WD MODE HW ONLY"]
},
"logger_level":
{
"enum":
["TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"]
},
"overcurrent_parameters_source":
{
"enum":
["FW_VALUES", "USER_CONFIG_VALUES",
"BOARD_CONFIG_VALUES", "OVERCURRENT_DISABLED",
"FW VALUES", "USER CONFIG VALUES",
"BOARD CONFIG VALUES", "OVERCURRENT DISABLED"]
},
"temperature_parameters_source":
{
"enum":
["FW_VALUES", "USER_CONFIG_VALUES",
"FW VALUES", "USER CONFIG VALUES"]
},
"conversion_time":
{
"enum":
[140, 204, 332, 588,
1100, 2116, 4156, 8244]
},
"uint16_t": {"type": "integer", "minimum": 0, "maximum": 65535},
"uint32_t": {"type": "integer", "minimum": 0, "maximum": 4294967295}
}
}

View File

@@ -0,0 +1,70 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file byte_order.h
* @brief Defines byte order operations.
**/
#ifndef __BYTE_ORDER_H__
#define __BYTE_ORDER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#if !defined(__BYTE_ORDER__)
// TODO: Check this better?
#if defined(_MSC_VER)
#define __ORDER_LITTLE_ENDIAN__ (1)
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#else
#error "Unexpected byte order"
#endif
#endif
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define BYTE_ORDER__htonl(x) (x)
#define BYTE_ORDER__ntohs(x) (x)
#define BYTE_ORDER__ntohl(x) (x)
#define BYTE_ORDER__htons(x) (x)
#define BYTE_ORDER__ntohll(x) (x)
#define BYTE_ORDER__htonll(x) (x)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define BYTE_ORDER__htons(n) ((uint16_t)((uint16_t)((((uint16_t)(n) & 0xFF)) << 8) | (((uint16_t)(n) & 0xFF00) >> 8)))
#define BYTE_ORDER__ntohs(n) ((uint16_t)((uint16_t)((((uint16_t)(n) & 0xFF)) << 8) | (((uint16_t)(n) & 0xFF00) >> 8)))
#define BYTE_ORDER__htonl(n) (((((uint32_t)(n) & 0xFF)) << 24) | \
((((uint32_t)(n) & 0xFF00)) << 8) | \
((((uint32_t)(n) & 0xFF0000)) >> 8) | \
((((uint32_t)(n) & 0xFF000000)) >> 24))
#define BYTE_ORDER__ntohl(n) (((((uint32_t)(n) & 0xFF)) << 24) | \
((((uint32_t)(n) & 0xFF00)) << 8) | \
((((uint32_t)(n) & 0xFF0000)) >> 8) | \
((((uint32_t)(n) & 0xFF000000)) >> 24))
#define BYTE_ORDER__htonll(n) (((uint64_t) BYTE_ORDER__htonl((n) & 0xFFFFFFFF) << 32) | \
(uint64_t) BYTE_ORDER__htonl((n) >> 32))
#define BYTE_ORDER__ntohll(n) (((uint64_t) BYTE_ORDER__htonl((n) & 0xFFFFFFFF) << 32) | \
(uint64_t) BYTE_ORDER__htonl((n) >> 32))
#endif
#define BYTE_ORDER__switch_endiannessl(n) (((((uint32_t)(n) & 0xFF)) << 24) | \
((((uint32_t)(n) & 0xFF00)) << 8) | \
((((uint32_t)(n) & 0xFF0000)) >> 8) | \
((((uint32_t)(n) & 0xFF000000)) >> 24))
#ifdef __cplusplus
}
#endif
#endif /* __BYTE_ORDER_H__ */

View File

@@ -0,0 +1,300 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file context_switch_defs.h
* @brief Declerations of all context switch related structs.
**/
#ifndef __CONTEXT_SWITCH_DEFS__
#define __CONTEXT_SWITCH_DEFS__
#ifdef __cplusplus
extern "C" {
#endif
#include "control_protocol.h"
/**********************************************************************
* Defines
**********************************************************************/
#define CONTEXT_SWITCH_DEFS__TIMESTAMP_INIT_VALUE (0xFFFFFFFF)
#define CONTEXT_SWITCH_DEFS__ENABLE_LCU_DEFAULT_KERNEL_ADDRESS (1)
#define CONTEXT_SWITCH_DEFS__ENABLE_LCU_DEFAULT_KERNEL_COUNT (2)
#define CONTEXT_SWITCH_DEFS__ENABLE_LCU_DEFAULT_BATCH_SIZE (1)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_SHIFT (0)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_WIDTH (4)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_MASK (0x0f)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_READ(src) \
(((uint8_t)(src) & CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_MASK) >> CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_SHIFT)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_SHIFT (CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_WIDTH)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_MASK (0x70)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_READ(src) \
(((uint8_t)(src) & CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_MASK) >> CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_SHIFT)
#define CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_SET(dst, cluster_index, lcu_index) \
(dst) = (((lcu_index) << CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_SHIFT) & CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_MASK) | \
(((cluster_index) << CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_SHIFT) & CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_MASK)
#pragma pack(push, 1)
typedef struct {
uint16_t core_bytes_per_buffer;
uint16_t core_buffers_per_frame;
uint16_t periph_bytes_per_buffer;
uint16_t periph_buffers_per_frame;
uint16_t feature_padding_payload;
uint16_t buffer_padding_payload;
uint16_t buffer_padding;
} CONTEXT_SWITCH_DEFS__stream_reg_info_t;
#if defined(_MSC_VER)
typedef enum : uint8_t {
#else
typedef enum __attribute__((packed)) {
#endif
CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_VDMA_DESCRIPTORS = 0,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_TRIGGER_SEQUENCER,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_DATA_FROM_VDMA_CHANNEL,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_LCU_DEFAULT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_LCU_NON_DEFAULT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DISABLE_LCU,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_BOUNDARY_INPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_BOUNDARY_OUTPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_INTER_CONTEXT_INPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_INTER_CONTEXT_OUTPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_DDR_BUFFER_INPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_DDR_BUFFER_OUTPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DEACTIVATE_VDMA_CHANNEL,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_CHANGE_VDMA_TO_STREAM_MAPPING,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ADD_DDR_PAIR_INFO,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_START,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_LCU_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_SEQUENCER_DONE_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_INPUT_CHANNEL_TRANSFER_DONE_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_OUTPUT_CHANNEL_TRANSFER_DONE_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_MODULE_CONFIG_DONE_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_APPLICATION_CHANGE_INTERRUPT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_CFG_CHANNEL,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DEACTIVATE_CFG_CHANNEL,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_REPEATED_ACTION,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_DMA_IDLE_ACTION,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS_IDLE,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_CCW_BURSTS,
/* Must be last */
CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT
} CONTEXT_SWITCH_DEFS__ACTION_TYPE_t;
typedef struct {
CONTEXT_SWITCH_DEFS__ACTION_TYPE_t action_type;
uint32_t time_stamp;
} CONTEXT_SWITCH_DEFS__common_action_header_t;
/**
* The layout of a repeated action in the action_list will be as follows:
* 1) CONTEXT_SWITCH_DEFS__common_action_header_t with 'action_type' CONTEXT_SWITCH_DEFS__ACTION_TYPE_REPEATED_ACTION
* 2) CONTEXT_SWITCH_DEFS__repeated_action_header_t
* 3) 'count' sub-actions whose type matches the 'sub_action_type' defined by (1).
* The sub-actions will be consecutive, and won't have 'CONTEXT_SWITCH_DEFS__common_action_header_t's
*
* E.g - 3 repeated 'CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t's:
* |-------------------------------------------------------------------------------------------------------|
* | action_list | data |
* |-------------------------------------------------------------------------------------------------------|
* | ... | |
* | | | CONTEXT_SWITCH_DEFS__common_action_header_t { |
* | | | .action_type = CONTEXT_SWITCH_DEFS__ACTION_TYPE_REPEATED_ACTION; |
* | | | .time_stamp = <time_of_last_executed_action_in_repeated>; |
* | | | } |
* | | | CONTEXT_SWITCH_DEFS__repeated_action_header_t { |
* | | | .count = 3; |
* | | | .last_executed = <last_action_executed_in_repeated>; |
* | | | .sub_action_type = CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_LCU_DEFAULT; |
* | | | } |
* | | | CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t { .packed_lcu_id=<some_lcu_id>; } |
* | | | CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t { .packed_lcu_id=<some_lcu_id>; } |
* | V | CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t { .packed_lcu_id=<some_lcu_id>; } |
* | ... | (Next action starting with CONTEXT_SWITCH_DEFS__common_action_header_t) |
* |-------------------------------------------------------------------------------------------------------|
* See also: "CONTROL_PROTOCOL__REPEATED_ACTION_t" in "control_protocol.h"
*/
typedef struct {
uint8_t count;
uint8_t last_executed;
CONTEXT_SWITCH_DEFS__ACTION_TYPE_t sub_action_type;
} CONTEXT_SWITCH_DEFS__repeated_action_header_t;
typedef struct {
uint16_t descriptors_count;
uint8_t cfg_channel_number;
} CONTEXT_SWITCH_DEFS__read_vdma_action_data_t;
typedef struct {
uint16_t ccw_bursts;
uint8_t cfg_channel_number;
} CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t;
typedef struct {
uint8_t cluster_index;
CONTORL_PROTOCOL__sequencer_config_t sequencer_config;
} CONTEXT_SWITCH_DEFS__trigger_sequencer_action_data_t;
typedef struct {
uint8_t packed_lcu_id;
uint16_t kernel_done_address;
uint32_t kernel_done_count;
} CONTEXT_SWITCH_DEFS__enable_lcu_action_non_default_data_t;
/* Default action - kernel_done_address and kernel_done_count has default values */
typedef struct {
uint8_t packed_lcu_id;
} CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t;
typedef struct {
uint8_t packed_lcu_id;
} CONTEXT_SWITCH_DEFS__disable_lcu_action_data_t;
typedef struct {
uint8_t vdma_channel_index;
uint8_t edge_layer_direction;
bool is_inter_context;
} CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t;
typedef struct {
uint8_t vdma_channel_index;
uint8_t stream_index;
uint32_t channel_credits;
uint8_t credit_type;
uint16_t periph_bytes_per_buffer;
} CONTEXT_SWITCH_DEFS__fetch_data_action_data_t;
typedef struct {
uint8_t vdma_channel_index;
uint8_t stream_index;
bool is_dummy_stream;
} CONTEXT_SWITCH_DEFS__change_vdma_to_stream_mapping_data_t;
typedef struct {
uint8_t h2d_vdma_channel_index;
uint8_t d2h_vdma_channel_index;
uint32_t descriptors_per_batch;
uint16_t programmed_descriptors_count;
} CONTEXT_SWITCH_DEFS__add_ddr_pair_info_action_data_t;
/* wait for interrupt structs */
typedef struct {
uint8_t packed_lcu_id;
} CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t;
typedef struct {
uint8_t vdma_channel_index;
} CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t;
typedef struct {
uint8_t sequencer_index;
} CONTEXT_SWITCH_DEFS__sequencer_interrupt_data_t;
typedef struct {
uint8_t aggregator_index;
uint8_t pred_cluster_ob_index;
uint8_t pred_cluster_ob_cluster_index;
uint8_t pred_cluster_ob_interface;
uint8_t succ_prepost_ob_index;
uint8_t succ_prepost_ob_interface;
} CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t;
typedef struct {
uint8_t vdma_channel_index;
uint8_t stream_index;
bool is_inter_context;
} CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t;
typedef struct {
uint8_t module_index;
} CONTEXT_SWITCH_DEFS__module_config_done_interrupt_data_t;
typedef struct {
uint8_t application_index;
} CONTEXT_SWITCH_DEFS__application_change_interrupt_data_t;
/* edge layers structs */
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
bool is_single_context_app;
} CONTEXT_SWITCH_DEFS__activate_boundary_input_data_t;
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
uint64_t host_descriptors_base_address;
uint16_t initial_host_available_descriptors;
uint8_t desc_list_depth;
} CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t;
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
uint64_t host_descriptors_base_address;
uint16_t initial_host_available_descriptors;
uint8_t desc_list_depth;
bool fw_managed_channel;
} CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t;
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
uint32_t frame_credits_in_bytes;
uint16_t desc_page_size;
} CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t;
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
// TODO: add this to CONTEXT_SWITCH_DEFS__stream_reg_info_t
uint32_t frame_credits_in_bytes;
uint64_t host_descriptors_base_address;
uint16_t initial_host_available_descriptors;
uint16_t desc_page_size;
uint8_t desc_list_depth;
} CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t;
typedef struct {
uint8_t stream_index;
uint8_t vdma_channel_index;
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
uint32_t frame_credits_in_bytes;
uint64_t host_descriptors_base_address;
uint16_t initial_host_available_descriptors;
uint16_t desc_page_size;
uint8_t desc_list_depth;
bool fw_managed_channel;
} CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t;
typedef struct {
uint8_t channel_index;
uint64_t host_descriptors_base_address;
uint16_t initial_host_available_descriptors;
} CONTEXT_SWITCH_DEFS__activate_cfg_channel_t;
typedef struct {
uint8_t channel_index;
} CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t;
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif /* __CONTEXT_SWITCH_DEFS__ */

File diff suppressed because it is too large Load Diff

167
common/include/d2h_events.h Normal file
View File

@@ -0,0 +1,167 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file d2h_events.h
* @brief Declares all d2h event manager structures relevant in the host.
**/
#ifndef __D2H_EVENTS_H__
#define __D2H_EVENTS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "status.h"
#include "stdfloat.h"
/**
* @brief The d2h event manager structures relevant in the host
*/
typedef enum {
D2H_EVENT_PRIORITY_INFO = 0,
D2H_EVENT_PRIORITY_CRITICAL,
/* Must be last */
D2H_EVENT_PRIORITY_COUNT
} D2H_EVENT_PRIORITY_t;
typedef enum {
D2H_EVENT_COMMUNICATION_TYPE_UDP = 0,
D2H_EVENT_COMMUNICATION_TYPE_PCIE,
D2H_EVENT_COMMUNICATION_TYPE__COUNT
} D2H_EVENT_COMMUNICATION_TYPE_t;
typedef struct {
uint32_t version;
uint32_t sequence;
uint32_t priority;
uint32_t module_id;
uint32_t event_id;
uint32_t parameter_count;
uint32_t payload_length;
} D2H_EVENT_HEADER_t;
/* D2H_EVENT_ID_t Should be in the same order as the structs in D2H_EVENT__message_parameters_t union, since the host will parse according to this enum */
/* For example ETHERNET_SERVICE_RX_ERROR_EVENT_ID is 0, so D2H_EVENT_rx_error_event_message_t is the first struct in D2H_EVENT__message_parameters_t */
typedef enum {
ETHERNET_SERVICE_RX_ERROR_EVENT_ID = 0,
D2H_HOST_INFO_EVENT_ID,
HEALTH_MONITOR_TEMPERATURE_ALARM_D2H_EVENT_ID,
HEALTH_MONITOR_CLOSED_STREAMS_D2H_EVENT_ID,
HEALTH_MONITOR_OVERCURRENT_PROTECTION_ALERT_EVENT_ID,
HEALTH_MONITOR_LCU_ECC_CORRECTABLE_EVENT_ID,
HEALTH_MONITOR_LCU_ECC_UNCORRECTABLE_EVENT_ID,
HEALTH_MONITOR_CPU_ECC_ERROR_EVENT_ID,
HEALTH_MONITOR_CPU_ECC_FATAL_EVENT_ID,
CONTEXT_SWITCH_BREAKPOINT_REACHED,
HEALTH_MONITOR_CLOCK_CHANGED_EVENT_ID,
D2H_EVENT_ID_COUNT /* Must be last*/
} D2H_EVENT_ID_t;
/* D2H_EVENT_rx_error_event_message_t should be the same as hailo_rx_error_notification_message_t */
typedef struct {
uint32_t error;
uint32_t queue_number;
uint32_t rx_errors_count;
} D2H_EVENT_rx_error_event_message_t;
#define D2H_EVENT_RX_ERROR_EVENT_PARAMETER_COUNT (3)
/* D2H_EVENT_host_info_event_message_t should be the same as hailo_debug_notification_message_t */
typedef struct {
uint32_t connection_status;
uint32_t connection_type;
uint32_t pcie_is_active;
uint32_t host_port;
uint32_t host_ip_addr;
} D2H_EVENT_host_info_event_message_t;
#define D2H_EVENT_HOST_INFO_EVENT_PARAMETER_COUNT (5)
/* D2H_EVENT_health_monitor_closed_streams_event_message_t should be the same as hailo_health_monitor_dataflow_shutdown_notification_message_t */
typedef struct {
uint32_t closed_input_streams;
uint32_t closed_output_streams;
float32_t ts0_temperature;
float32_t ts1_temperature;
} D2H_EVENT_health_monitor_closed_streams_event_message_t;
#define D2H_EVENT_HEALTH_MONITOR_CLOSED_STREAMS_EVENT_PARAMETER_COUNT (4)
/* D2H_EVENT_health_monitor_temperature_alarm_event_message_t should be the same as hailo_health_monitor_temperature_alarm_notification_message_t */
typedef struct {
uint32_t temperature_zone;
uint32_t alarm_ts_id;
float32_t ts0_temperature;
float32_t ts1_temperature;
} D2H_EVENT_health_monitor_temperature_alarm_event_message_t;
#define D2H_EVENT_HEALTH_MONITOR_TEMPERATURE_ALARM_EVENT_PARAMETER_COUNT (4)
/* D2H_EVENT_health_monitor_overcurrent_alert_event_message_t should be the same as hailo_health_monitor_overcurrent_alert_notification_message_t */
typedef struct {
uint32_t overcurrent_zone;
float32_t exceeded_alert_threshold;
float32_t sampled_current_during_alert;
} D2H_EVENT_health_monitor_overcurrent_alert_event_message_t;
#define D2H_EVENT_HEALTH_MONITOR_OVERCURRENT_ALERT_EVENT_PARAMETER_COUNT (2)
/* D2H_EVENT_health_monitor_lcu_ecc_error_event_message_t should be the same as hailo_health_monitor_lcu_ecc_error_notification_message_t */
typedef struct {
uint16_t cluster_bitmap;
} D2H_EVENT_health_monitor_lcu_ecc_error_event_message_t;
/* D2H_EVENT_health_monitor_cpu_ecc_event_message_t should be the same as hailo_health_monitor_cpu_ecc_error_notification_message_t */
#define D2H_EVENT_HEALTH_MONITOR_LCU_ECC_ERROR_EVENT_PARAMETER_COUNT (1)
typedef struct {
uint32_t memory_bitmap;
} D2H_EVENT_health_monitor_cpu_ecc_event_message_t;
#define D2H_EVENT_HEALTH_MONITOR_CPU_ECC_EVENT_PARAMETER_COUNT (1)
/* D2H_EVENT_context_switch_breakpoint_reached_event_massage_t should be the same as
* CONTROL_PROTOCOL__context_switch_breakpoint_data_t and hailo_context_switch_breakpoint_reached_notification_message_t */
typedef struct {
uint8_t application_index;
uint16_t batch_index;
uint8_t context_index;
uint16_t action_index;
} D2H_EVENT_context_switch_breakpoint_reached_event_massage_t;
#define D2H_EVENT_CONTEXT_SWITCH_BREAKPOINT_REACHED_EVENT_PARAMETER_COUNT (4)
typedef struct {
uint32_t previous_clock;
uint32_t current_clock;
} D2H_EVENT_health_monitor_clock_changed_event_message_t;
#define D2H_EVENT_HEALTH_MONITOR_CLOCK_CHANGED_EVENT_PARAMETER_COUNT (2)
/* D2H_EVENT__message_parameters_t should be in the same order as hailo_notification_message_parameters_t */
typedef union {
D2H_EVENT_rx_error_event_message_t rx_error_event;
D2H_EVENT_host_info_event_message_t host_info_event;
D2H_EVENT_health_monitor_closed_streams_event_message_t health_monitor_closed_streams_event;
D2H_EVENT_health_monitor_temperature_alarm_event_message_t health_monitor_temperature_alarm_event;
D2H_EVENT_health_monitor_overcurrent_alert_event_message_t health_monitor_overcurrent_alert_event;
D2H_EVENT_health_monitor_lcu_ecc_error_event_message_t health_monitor_lcu_ecc_error_event;
D2H_EVENT_health_monitor_cpu_ecc_event_message_t health_monitor_cpu_ecc_event;
D2H_EVENT_context_switch_breakpoint_reached_event_massage_t context_switch_breakpoint_reached_event;
D2H_EVENT_health_monitor_clock_changed_event_message_t health_monitor_clock_changed_event;
} D2H_EVENT__message_parameters_t;
typedef struct {
D2H_EVENT_HEADER_t header;
D2H_EVENT__message_parameters_t message_parameters;
} D2H_EVENT_MESSAGE_t;
#define PCIE_D2H_EVENT_MAX_SIZE (0x370)
/**********************************************************************
* Public Functions
**********************************************************************/
HAILO_COMMON_STATUS_t D2H_EVENTS__parse_event(D2H_EVENT_MESSAGE_t *d2h_event_message);
#ifdef __cplusplus
}
#endif
#endif /* __D2H_EVENTS_H__ */

View File

@@ -0,0 +1,85 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file firmware_header.h
* @brief Contains definitions needed for generating and handling a firmware header.
**/
#ifndef __FIRMWARE_HEADER__
#define __FIRMWARE_HEADER__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "utils.h"
#define FIRMWARE_HEADER_MAGIC_HAILO8 (0x1DD89DE0)
#define FIRMWARE_HEADER_MAGIC_MERCURY (0xE905DAAB)
typedef enum {
FIRMWARE_HEADER_VERSION_INITIAL = 0,
/* MUST BE LAST */
FIRMWARE_HEADER_VERSION_COUNT
} firmware_header_version_t;
typedef enum {
FIRMWARE_TYPE_HAILO8 = 0,
FIRMWARE_TYPE_MERCURY
} firmware_type_t;
#ifdef MERCURY
#define COMPILED_FIRMWARE_TYPE (FIRMWARE_TYPE_MERCURY)
#elif defined(HAILO8_B0)
#define COMPILED_FIRMWARE_TYPE (FIRMWARE_TYPE_HAILO8)
#endif /* MERCURY */
typedef struct {
uint32_t magic;
uint32_t header_version;
uint32_t firmware_major;
uint32_t firmware_minor;
uint32_t firmware_revision;
uint32_t code_size;
} firmware_header_t;
#if defined(_MSC_VER)
// TODO: warning C4200
#pragma warning(push)
#pragma warning(disable: 4200)
#endif
typedef struct {
uint32_t key_size;
uint32_t content_size;
uint8_t certificates_data[0];
} secure_boot_certificate_t;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#define MINIMUM_FIRMWARE_CODE_SIZE (20*4)
// Tightly coupled with ld script
#define MAXIMUM_APP_FIRMWARE_CODE_SIZE (0x40000)
#define MAXIMUM_CORE_FIRMWARE_CODE_SIZE (0x18000)
#define MAXIMUM_SECOND_STAGE_CODE_SIZE (0x80000)
#define MAXIMUM_FIRMWARE_CERT_KEY_SIZE (0x1000)
#define MAXIMUM_FIRMWARE_CERT_CONTENT_SIZE (0x1000)
typedef enum {
FW_BINARY_TYPE_INVALID = 0,
FW_BINARY_TYPE_APP_FIRMWARE,
FW_BINARY_TYPE_CORE_FIRMWARE,
FW_BINARY_TYPE_SECOND_STAGE_BOOT
} FW_BINARY_TYPE_t;
#ifdef __cplusplus
}
#endif
#endif /* __FIRMWARE_HEADER__ */

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file firmware_header_utils.h
* @brief Utilities for working with the firmware header.
**/
#ifndef __FIRMWARE_HEADER_UTILS__
#define __FIRMWARE_HEADER_UTILS__
#include <stdint.h>
#include <stdbool.h>
#include "status.h"
#include "firmware_header.h"
#include "firmware_version.h"
#ifdef __cplusplus
extern "C" {
#endif
#define REVISION_NUMBER_SHIFT (0)
#define REVISION_APP_CORE_FLAG_BIT_SHIFT (27)
#define REVISION_RESERVED_0_FLAG_BIT_SHIFT (28)
#define REVISION_RESERVED_1_FLAG_BIT_SHIFT (29)
#define REVISION_DEV_FLAG_BIT_SHIFT (30)
#define REVISION_SECOND_STAGE_FLAG_BIT_SHIFT (31)
#define REVISION_NUMBER_WIDTH (27U)
#define REVISION_APP_CORE_FLAG_BIT_WIDTH (1U)
#define REVISION_RESERVED_0_FLAG_BIT_WIDTH (1U)
#define REVISION_RESERVED_1_FLAG_BIT_WIDTH (1U)
#define REVISION_DEV_FLAG_BIT_WIDTH (1U)
#define REVISION_SECOND_STAGE_FLAG_BIT_WIDTH (1U)
#define REVISION_NUMBER_MASK (GET_MASK(REVISION_NUMBER_WIDTH, REVISION_NUMBER_SHIFT))
#define REVISION_APP_CORE_FLAG_BIT_MASK (GET_MASK(REVISION_APP_CORE_FLAG_BIT_WIDTH, REVISION_APP_CORE_FLAG_BIT_SHIFT))
#define REVISION_RESERVED_0_FLAG_BIT_MASK (GET_MASK(REVISION_RESERVED_0_FLAG_BIT_WIDTH, REVISION_RESERVED_0_FLAG_BIT_SHIFT))
#define REVISION_RESERVED_1_FLAG_BIT_MASK (GET_MASK(REVISION_RESERVED_1_FLAG_BIT_WIDTH, REVISION_RESERVED_1_FLAG_BIT_SHIFT))
#define REVISION_DEV_FLAG_BIT_MASK (GET_MASK(REVISION_DEV_FLAG_BIT_WIDTH, REVISION_DEV_FLAG_BIT_SHIFT))
#define REVISION_SECOND_STAGE_FLAG_BIT_MASK (GET_MASK(REVISION_SECOND_STAGE_FLAG_BIT_WIDTH, REVISION_SECOND_STAGE_FLAG_BIT_SHIFT))
#define GET_REVISION_NUMBER_VALUE(binary_revision) (REVISION_NUMBER_MASK & binary_revision)
#define IS_REVISION_DEV(binary_revision) (REVISION_DEV_FLAG_BIT_MASK == (REVISION_DEV_FLAG_BIT_MASK & binary_revision))
#define DEV_STRING_NOTE(__is_release) ((__is_release)? "" : " (dev)")
/**
* Validates the FW headers.
* this function is used from the firmware, from HailoRT and from the second_stage bootloader to validate the headers.
* @param[in] address Address of the firmware.
* @param[in] firmware_size Size of the firmware.
* If the actual size is unknown, set this to the maximum possible size (for example the size of the Flash
* section holding the FW).
* @param[in] is_firmware_size_unknown Set to true if the firmware size is unknown (for example when loading from Flash).
* @param[out] out_app_firmware_header (optional) App firmware header
* @param[out] out_core_firmware_header (optional) Core firmware header
* @param[out] out_firmware_cert (optional) Firmware certificate header
*/
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_fw_headers(uintptr_t firmware_base_address,
uint32_t firmware_size,
bool is_firmware_size_unknown,
firmware_header_t **out_app_firmware_header,
firmware_header_t **out_core_firmware_header,
secure_boot_certificate_t **out_firmware_cert,
firmware_type_t firmware_type);
/**
* Validates the Second stage headers.
* this function is used from the firmware and from HailoRT to validate the headers.
* @param[in] address Address of the second stage.
* @param[in] second_stage_size Size of the second_stage.
* If the actual size is unknown, set this to the maximum possible size (for example the size of the Flash
* section holding the Second stage).
* @param[out] out_second_stage_header (optional) second_stage header
*/
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_second_stage_headers(uintptr_t second_stage_base_size,
uint32_t second_stage_size,
firmware_header_t **out_second_stage_header,
firmware_type_t firmware_type);
/**
* Returns the binary type (App firmware, Core firmware or Second Stage boot)
* @param[in] binary_revision The binary revision (Third part in binary version)
*/
FW_BINARY_TYPE_t FIRMWARE_HEADER_UTILS__get_fw_binary_type(uint32_t binary_revision);
/**
* Returns true if the new binary version is older then the minumum allowed.
* @param[in] new_binary_version A pointer to the new binary version to update to
* @param[in] minimum_allowed_binary_version A pointer to the minimum binary version that is allowed to be upgraded to
*/
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__is_binary_being_downgraded(const firmware_version_t *new_binary_version,
const firmware_version_t *minimum_allowed_binary_version);
/**
* Validates the binary version to prevent downgrade.
* this function is used from the firmware and from HailoRT to prevent downgrade.
* @param[in] new_binary_version A pointer to the new binary version to update to
* @param[in] minimum_allowed_binary_version A pointer to the minimum binary version that is allowed to be upgraded to
* @param[in] fw_binary_type A bit that indicates which binary type is passed (app firmware, core firmware, second stage boot)
*/
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_binary_version(const firmware_version_t *new_binary_version,
const firmware_version_t *minimum_allowed_binary_version,
FW_BINARY_TYPE_t fw_binary_type);
#ifdef __cplusplus
}
#endif
#endif /* __FIRMWARE_HEADER_UTILS__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file firmware_version.h
* @brief Contains information regarding the firmware version.
**/
#ifndef __FIRMWARE_VERSION__
#define __FIRMWARE_VERSION__
#include <stdint.h>
typedef struct {
uint32_t firmware_major;
uint32_t firmware_minor;
uint32_t firmware_revision;
} firmware_version_t;
#define PACK_FW_VERSION(major, minor, revision) {(major), (minor), (revision)}
#define MINIMUM_SECURED_FW_VERSION (firmware_version_t)PACK_FW_VERSION(2, 6, 0)
const firmware_version_t* FIRMWARE_VERSION__get_version(void);
#endif /* __FIRMWARE_VERSION__ */

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file logger_level.h
* @brief Contains the possible logger level information.
**/
#ifndef __LOGGER_LEVEL__
#define __LOGGER_LEVEL__
typedef enum {
FW_LOGGER_LEVEL_TRACE = 0,
FW_LOGGER_LEVEL_DEBUG,
FW_LOGGER_LEVEL_INFO,
FW_LOGGER_LEVEL_WARN,
FW_LOGGER_LEVEL_ERROR,
FW_LOGGER_LEVEL_FATAL
} FW_LOGGER_LEVEL_t;
#endif //__LOGGER_LEVEL__

49
common/include/md5.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* See md5.c for more information.
*/
#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#elif !defined(_MD5_H)
#define _MD5_H
/** Start of modifications for the open source file. **/
#include "stdint.h"
typedef uint8_t MD5_SUM_t[16];
/* Any 32-bit or wider unsigned integer data type will do */
typedef size_t MD5_u32plus;
/** End of modifications. **/
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
extern void MD5_Init(MD5_CTX *ctx);
extern void MD5_Update(MD5_CTX *ctx, const void *data, size_t size);
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
#endif

View File

@@ -0,0 +1,68 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file sensor_config_exports.h
* @brief Sensor config exported defines.
**/
#ifndef __SENSOR_CONFIG_EXPORT__
#define __SENSOR_CONFIG_EXPORT__
#define MAX_CONFIG_NAME_LEN 100
#pragma pack(push, 1)
typedef struct {
uint8_t operation;
uint8_t length; //how many bits of the register
uint8_t page; //If SOC is limited to 8 bit addressing, or some array imager.
uint32_t address;
uint32_t bitmask;
uint32_t value; //8/16/32-bit register value
} SENSOR_CONFIG__operation_cfg_t;
#pragma pack(pop)
typedef struct {
uint32_t sensor_type;
uint32_t config_size;
uint16_t reset_config_size;
uint8_t is_free;
uint8_t no_reset_offset;
uint16_t config_height;
uint16_t config_width;
uint16_t config_fps;
uint16_t section_version;
uint8_t config_name[MAX_CONFIG_NAME_LEN];
} SENSOR_CONFIG__section_info_t;
typedef enum {
SENSOR_CONFIG_OPCODES_WR = 0,
SENSOR_CONFIG_OPCODES_RD,
SENSOR_CONFIG_OPCODES_RMW,
SENSOR_CONFIG_OPCODES_DELAY,
} SENSOR_CONFIG_OPCODES_t;
typedef struct {
uint8_t bus_index;
uint16_t slave_address;
uint8_t register_address_size;
bool should_hold_bus;
uint8_t endianness;
} SENSOR_I2C_SLAVE_INFO_t;
typedef enum {
I2C_SLAVE_ENDIANNESS_BIG_ENDIAN = 0,
I2C_SLAVE_ENDIANNESS_LITTLE_ENDIAN = 1,
I2C_SLAVE_ENDIANNESS_COUNT
} i2c_slave_endianness_t;
#define SENSOR_CONFIG__TOTAL_SECTIONS_BLOCK_COUNT (8)
#define SENSOR_CONFIG__SENSOR_SECTION_BLOCK_COUNT (7)
#define SENSOR_CONFIG__ISP_SECTIONS_BLOCK_COUNT (SENSOR_CONFIG__TOTAL_SECTIONS_BLOCK_COUNT - SENSOR_CONFIG__SENSOR_SECTION_BLOCK_COUNT)
#define SENSOR_CONFIG__ISP_SECTION_INDEX (SENSOR_CONFIG__TOTAL_SECTIONS_BLOCK_COUNT - SENSOR_CONFIG__ISP_SECTIONS_BLOCK_COUNT)
#define SENSOR_SECTIONS_INFO_SIZE (SENSOR_CONFIG__TOTAL_SECTIONS_BLOCK_COUNT * sizeof(SENSOR_CONFIG__section_info_t))
#endif /* __SENSOR_CONFIG_EXPORT__ */

61
common/include/status.h Normal file
View File

@@ -0,0 +1,61 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file status.h
* @brief Declares status enum for hailo c platform.
**/
#ifndef __STATUS_H__
#define __STATUS_H__
/**
* @brief The enumeration of all status codes.
*/
typedef enum {
/* global statuses */
HAILO_COMMON_STATUS__SUCCESS = 0,
HAILO_COMMON_STATUS__UNINITIALIZED,
/* Control protocol module errors */
HAILO_STATUS__CONTROL_PROTOCOL__OVERRUN_BEFORE_PARAMETER = 0x1000,
HAILO_STATUS__CONTROL_PROTOCOL__NULL_ARGUMENT_PASSED,
HAILO_STATUS__CONTROL_PROTOCOL__OVERRUN_AT_PARAMETER,
HAILO_STATUS__CONTROL_PROTOCOL__UNEXPECTED_ACK_VALUE,
HAILO_STATUS__CONTROL_PROTOCOL__INVALID_VERSION,
HAILO_STATUS__CONTROL_PROTOCOL__PART_OF_THE_MESSAGE_NOT_PARSED,
HAILO_STATUS__CONTROL_PROTOCOL__INVALID_BUFFER_SIZE,
HAILO_STATUS__CONTROL_PROTOCOL__INVALID_ARGUMENT,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__CERT_TOO_LARGE = 0x2000,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_HEADER_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INCORRECT_FIRMWARE_HEADER_MAGIC,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__UNSUPPORTED_FIRMWARE__HEADER_VERSION,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__CODE_SIZE_BELOW_MINIMUM,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__CODE_OVERRUNS_RAM_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_CODE_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_HEADER_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_KEY_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_CONTENT_SIZE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_HEADER,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_CERTIFICATE_HEADER,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CORE_CPU_FIRMWARE_HEADER,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CORE_CPU_FIRMWARE_CERTIFICATE_HEADER,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__LEFTOVER_DATA_AFTER_LAST_FIRMWARE_HEADER,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__DETECTED_PROHIBITED_DOWNGRADE_ATTEMPT,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_BINARY_TYPE,
HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_TYPE,
HAILO_STATUS__D2H_EVENTS__INCORRECT_PARAMETER_COUNT = 0x3000,
HAILO_STATUS__D2H_EVENTS__INCORRECT_PARAMETER_LENGTH,
HAILO_STATUS__D2H_EVENTS__INVALID_ARGUMENT,
HAILO_STATUS__FIRMWARE_STATUS__NULL_ARGUMENT_PASSED = 0x4000,
HAILO_STATUS__FIRMWARE_STATUS__INVALID_COMPONENT_ID,
HAILO_STATUS__FIRMWARE_STATUS__INVALID_MODULE_ID,
HAILO_STATUS__FIRMWARE_STATUS__INVALID_STATUS_VALUE,
} HAILO_COMMON_STATUS_t;
#endif /* __STATUS_H__ */

16
common/include/stdfloat.h Normal file
View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file stdfloat.h
* @brief Defines fixed-size float types.
**/
#ifndef _STDFLOAT_H
#define _STDFLOAT_H
typedef float float32_t;
typedef double float64_t;
#endif /* _STDFLOAT_H */

View File

@@ -0,0 +1,101 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file user_config_common.h
* @brief Contains information regarding the firmware user config.
**/
#ifndef __USER_CONFIG_COMMON__
#define __USER_CONFIG_COMMON__
#include <stdint.h>
#include "logger_level.h"
#define USER_CONFIG_OVERCURRENT_UNINITIALIZED_VALUE (0)
#define USER_CONFIG_TEMPERATURE_DEFAULT_RED_ALARM_THRESHOLD (120.f)
#define USER_CONFIG_TEMPERATURE_DEFAULT_RED_HYSTERESIS_ALARM_THRESHOLD (116.f)
#define USER_CONFIG_TEMPERATURE_DEFAULT_ORANGE_ALARM_THRESHOLD (104.f)
#define USER_CONFIG_TEMPERATURE_DEFAULT_ORANGE_HYSTERESIS_ALARM_THRESHOLD (99.f)
#pragma pack(push, 1)
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4200)
#endif
typedef struct {
uint32_t magic;
uint32_t version;
uint32_t entry_count;
uint8_t entries[0];
} USER_CONFIG_header_t;
typedef struct {
uint16_t category;
uint16_t entry_id;
uint32_t entry_size;
uint8_t value[0];
} USER_CONFIG_ENTRY_t;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#pragma pack(pop)
// Used by user config defaults
typedef enum {
ASPM_DISABLED = 0,
ASPM_L1_ONLY,
ASPM_L0S_L1
} PCIE_CONFIG_SUPPOPRTED_ASPM_STATES_t;
typedef enum {
ASPM_L1_SUBSTATES_DISABLED = 0,
ASPM_L1_SUBSTATES_L11_ONLY,
ASPM_L1_SUBSTATES_L11_L12
} PCIE_CONFIG_SUPPOPRTED_L1_ASPM_SUBSTATES_t;
typedef enum {
SOC__NN_CLOCK_400MHz = 400 * 1000 * 1000,
SOC__NN_CLOCK_375MHz = 375 * 1000 * 1000,
SOC__NN_CLOCK_350MHz = 350 * 1000 * 1000,
SOC__NN_CLOCK_325MHz = 325 * 1000 * 1000,
SOC__NN_CLOCK_300MHz = 300 * 1000 * 1000,
SOC__NN_CLOCK_275MHz = 275 * 1000 * 1000,
SOC__NN_CLOCK_250MHz = 250 * 1000 * 1000,
SOC__NN_CLOCK_225MHz = 225 * 1000 * 1000,
SOC__NN_CLOCK_200MHz = 200 * 1000 * 1000,
SOC__NN_CLOCK_100MHz = 100 * 1000 * 1000
} SOC__NN_CLOCK_HZ_t;
typedef enum {
WD_SERVICE_MODE_HW_SW = 0,
WD_SERVICE_MODE_HW_ONLY,
WD_SERVICE_NUM_MODES
} WD_SERVICE_wd_mode_t;
typedef enum {
OVERCURRENT_PARAMETERS_SOURCE_FW_VALUES = 0,
OVERCURRENT_PARAMETERS_SOURCE_USER_CONFIG_VALUES,
OVERCURRENT_PARAMETERS_SOURCE_BOARD_CONFIG_VALUES,
OVERCURRENT_PARAMETERS_SOURCE_OVERCURRENT_DISABLED,
} OVERCURRENT_parameters_source_t;
typedef enum {
OVERCURRENT_CONVERSION_PERIOD_140US = 140,
OVERCURRENT_CONVERSION_PERIOD_204US = 204,
OVERCURRENT_CONVERSION_PERIOD_332US = 332,
OVERCURRENT_CONVERSION_PERIOD_588US = 588,
OVERCURRENT_CONVERSION_PERIOD_1100US = 1100,
OVERCURRENT_CONVERSION_PERIOD_2116US = 2116,
OVERCURRENT_CONVERSION_PERIOD_4156US = 4156,
OVERCURRENT_CONVERSION_PERIOD_8244US = 8244
} OVERCURRENT_conversion_time_us_t;
typedef enum {
TEMPERATURE_PROTECTION_PARAMETERS_SOURCE_FW_VALUES = 0,
TEMPERATURE_PROTECTION_PARAMETERS_SOURCE_USER_CONFIG_VALUES
} TEMPERATURE_PROTECTION_parameters_source_t;
#endif /* __USER_CONFIG_COMMON__ */

114
common/include/utils.h Normal file
View File

@@ -0,0 +1,114 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file utils.h
* @brief Defines common utilities.
**/
#ifndef __UTILS_H__
#define __UTILS_H__
/** A compile time assertion check.
*
* Validate at compile time that the predicate is true without
* generating code. This can be used at any point in a source file
* where typedef is legal.
*
* On success, compilation proceeds normally.
*
* On failure, attempts to typedef an array type of negative size. The
* offending line will look like
* typedef assertion_failed_file_h_42[-1]
* where file is the content of the second parameter which should
* typically be related in some obvious way to the containing file
* name, 42 is the line number in the file on which the assertion
* appears, and -1 is the result of a calculation based on the
* predicate failing.
*
* \param predicate The predicate to test. It must evaluate to
* something that can be coerced to a normal C boolean.
*
* \param file A sequence of legal identifier characters that should
* uniquely identify the source file in which this condition appears.
*/
#define CASSERT(predicate, file) \
_impl_CASSERT_LINE(predicate,__LINE__,file) \
#define _impl_PASTE(a,b) a##b
#define _impl_CASSERT_LINE(predicate, line, file) \
ATTR_UNUSED typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
#define ARRAY_LENGTH(__array) (sizeof((__array)) / sizeof((__array)[0]))
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef DIV_ROUND_UP
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#endif
#ifndef ROUND_UNSIGNED_FLOAT
#define ROUND_UNSIGNED_FLOAT(n) ((n - (uint32_t)(n)) > 0.5) ? (uint32_t)(n + 1) : (uint32_t)(n)
#endif
#ifndef IS_POWEROF2
#define IS_POWEROF2(v) ((v & (v - 1)) == 0)
#endif
#define CPU_CYCLES_NUMBER_IN_MS (configCPU_CLOCK_HZ / 1000)
#define GET_MASK(width, shift) (((1U << (width)) - 1U) << (shift))
/* Argument counter for variadic macros */
#define GET_ARG_COUNT(...) INTERNAL_GET_ARG_COUNT_PRIVATE(0, ## __VA_ARGS__, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define INTERNAL_GET_ARG_COUNT_PRIVATE(_0, _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, _17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, _33_, _34_, _35_, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, count, ...) count
#ifdef __GNUC__
#define ATTR_UNUSED __attribute__((unused))
#else
#define ATTR_UNUSED
#endif
#define PP_ARG_N(_1, _2, _3, _4, _5, _6, N, ...) N
#define PP_RSEQ_N() 6, 5, 4, 3, 2, 1, 0
#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)
#define PP_COMMASEQ_N() 1, 1, 1, 1, 1, 0
#define PP_COMMA(...) ,
#define PP_NARG_HELPER3_01(N) 0
#define PP_NARG_HELPER3_00(N) 1
#define PP_NARG_HELPER3_11(N) N
#define PP_NARG_HELPER2(a, b, N) PP_NARG_HELPER3_ ## a ## b(N)
#define PP_NARG_HELPER1(a, b, N) PP_NARG_HELPER2(a, b, N)
#define PP_HASCOMMA(...) \
PP_NARG_(__VA_ARGS__, PP_COMMASEQ_N())
#define PP_NARG(...) \
PP_NARG_HELPER1( \
PP_HASCOMMA(__VA_ARGS__), \
PP_HASCOMMA(PP_COMMA __VA_ARGS__ ()),\
PP_NARG_(__VA_ARGS__, PP_RSEQ_N()))
#define UNUSED0(...)
#define UNUSED1(x) (void)(x)
#define UNUSED2(x,y) (void)(x),(void)(y)
#define UNUSED3(x,y,z) (void)(x),(void)(y),(void)(z)
#define UNUSED4(a,x,y,z) (void)(a),(void)(x),(void)(y),(void)(z)
#define UNUSED5(a,b,x,y,z) (void)(a),(void)(b),(void)(x),(void)(y),(void)(z)
#define UNUSED6(a,b,x,y,z,c) (void)(a),(void)(b),(void)(x),(void)(y),(void)(z),(void)(c)
#define ALL_UNUSED_IMPL_(nargs) UNUSED ## nargs
#define ALL_UNUSED_IMPL(nargs) ALL_UNUSED_IMPL_(nargs)
#define ALL_UNUSED(...) ALL_UNUSED_IMPL( PP_NARG(__VA_ARGS__))(__VA_ARGS__ )
#endif /* __UTILS_H__ */

View File

@@ -0,0 +1,279 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file firmware_header_utils.c
* @brief Utilities for working with the firmware header.
**/
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "firmware_header.h"
#include "firmware_version.h"
#include "firmware_header_utils.h"
#include "utils.h"
#include "control_protocol.h"
/* when reading the firmware we don't want to read past the firmware_size,
so we have a consumed_firmware_offset that is updated _before_ accessing data at that offset
of firmware_base_address */
#define CONSUME_FIRMWARE(__size, __status) do { \
consumed_firmware_offset += (uint32_t) (__size); \
if ((firmware_size < (__size)) || (firmware_size < consumed_firmware_offset)) { \
status = __status; \
goto exit; \
} \
} while(0)
static HAILO_COMMON_STATUS_t firmware_header_utils__validate_fw_header(uintptr_t firmware_base_address,
uint32_t firmware_size,
uint32_t max_code_size,
uint32_t *outer_consumed_firmware_offset,
firmware_header_t **out_firmware_header,
firmware_type_t firmware_type)
{
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
firmware_header_t *firmware_header = NULL;
uint32_t consumed_firmware_offset = *outer_consumed_firmware_offset;
uint32_t firmware_magic = 0;
firmware_header = (firmware_header_t *) (firmware_base_address + consumed_firmware_offset);
CONSUME_FIRMWARE(sizeof(firmware_header_t), HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_HEADER_SIZE);
switch (firmware_type) {
case FIRMWARE_TYPE_HAILO8:
firmware_magic = FIRMWARE_HEADER_MAGIC_HAILO8;
break;
case FIRMWARE_TYPE_MERCURY:
firmware_magic = FIRMWARE_HEADER_MAGIC_MERCURY;
break;
default:
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_TYPE;
goto exit;
}
if (firmware_magic != firmware_header->magic) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INCORRECT_FIRMWARE_HEADER_MAGIC;
goto exit;
}
/* Validate that the firmware header version is supported */
switch(firmware_header->header_version) {
case FIRMWARE_HEADER_VERSION_INITIAL:
break;
default:
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__UNSUPPORTED_FIRMWARE__HEADER_VERSION;
goto exit;
break;
}
if (MINIMUM_FIRMWARE_CODE_SIZE > firmware_header->code_size) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__CODE_SIZE_BELOW_MINIMUM;
goto exit;
}
if (max_code_size < firmware_header->code_size) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__CODE_OVERRUNS_RAM_SIZE;
goto exit;
}
CONSUME_FIRMWARE(firmware_header->code_size, HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_FIRMWARE_CODE_SIZE);
*outer_consumed_firmware_offset = consumed_firmware_offset;
*out_firmware_header = firmware_header;
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}
static HAILO_COMMON_STATUS_t firmware_header_utils__validate_cert_header(uintptr_t firmware_base_address,
uint32_t firmware_size,
uint32_t *outer_consumed_firmware_offset,
secure_boot_certificate_t **out_firmware_cert)
{
secure_boot_certificate_t *firmware_cert = NULL;
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
uint32_t consumed_firmware_offset = *outer_consumed_firmware_offset;
firmware_cert = (secure_boot_certificate_t *) (firmware_base_address + consumed_firmware_offset);
CONSUME_FIRMWARE(sizeof(secure_boot_certificate_t), HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_HEADER_SIZE);
if ((MAXIMUM_FIRMWARE_CERT_KEY_SIZE < firmware_cert->key_size) ||
(MAXIMUM_FIRMWARE_CERT_CONTENT_SIZE < firmware_cert->content_size)) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__CERT_TOO_LARGE;
goto exit;
}
CONSUME_FIRMWARE(firmware_cert->key_size, HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_KEY_SIZE);
CONSUME_FIRMWARE(firmware_cert->content_size, HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CERT_CONTENT_SIZE);
*outer_consumed_firmware_offset = consumed_firmware_offset;
*out_firmware_cert = firmware_cert;
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_fw_headers(uintptr_t firmware_base_address,
uint32_t firmware_size,
bool is_firmware_size_unknown,
firmware_header_t **out_app_firmware_header,
firmware_header_t **out_core_firmware_header,
secure_boot_certificate_t **out_firmware_cert,
firmware_type_t firmware_type)
{
firmware_header_t *app_firmware_header = NULL;
firmware_header_t *core_firmware_header = NULL;
secure_boot_certificate_t *firmware_cert = NULL;
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
uint32_t consumed_firmware_offset = 0;
status = firmware_header_utils__validate_fw_header(firmware_base_address, firmware_size, MAXIMUM_APP_FIRMWARE_CODE_SIZE,
&consumed_firmware_offset, &app_firmware_header, firmware_type);
if (HAILO_COMMON_STATUS__SUCCESS != status) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_HEADER;
goto exit;
}
status = firmware_header_utils__validate_cert_header(firmware_base_address, firmware_size,
&consumed_firmware_offset, &firmware_cert);
if (HAILO_COMMON_STATUS__SUCCESS != status) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_CERTIFICATE_HEADER;
goto exit;
}
status = firmware_header_utils__validate_fw_header(firmware_base_address, firmware_size, MAXIMUM_CORE_FIRMWARE_CODE_SIZE,
&consumed_firmware_offset, &core_firmware_header, firmware_type);
if (HAILO_COMMON_STATUS__SUCCESS != status) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_CORE_CPU_FIRMWARE_HEADER;
goto exit;
}
if ((consumed_firmware_offset != firmware_size) && (!is_firmware_size_unknown)) {
/* it is an error if there is leftover data after the last firmware header */
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__LEFTOVER_DATA_AFTER_LAST_FIRMWARE_HEADER;
goto exit;
}
/* the out params are all optional */
if (NULL != out_app_firmware_header) {
*out_app_firmware_header = app_firmware_header;
}
if (NULL != out_firmware_cert) {
*out_firmware_cert = firmware_cert;
}
if (NULL != out_core_firmware_header) {
*out_core_firmware_header = core_firmware_header;
}
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_second_stage_headers(uintptr_t second_stage_base_size,
uint32_t second_stage_size,
firmware_header_t **out_second_stage_header,
firmware_type_t firmware_type)
{
firmware_header_t *second_stage_header = NULL;
secure_boot_certificate_t *second_stage_cert = NULL;
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
uint32_t consumed_second_stage_offset = 0;
status = firmware_header_utils__validate_fw_header(second_stage_base_size, second_stage_size, MAXIMUM_SECOND_STAGE_CODE_SIZE,
&consumed_second_stage_offset, &second_stage_header, firmware_type);
if (HAILO_COMMON_STATUS__SUCCESS != status) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_HEADER;
goto exit;
}
status = firmware_header_utils__validate_cert_header(second_stage_base_size, second_stage_size,
&consumed_second_stage_offset, &second_stage_cert);
if (HAILO_COMMON_STATUS__SUCCESS != status) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_APP_CPU_FIRMWARE_CERTIFICATE_HEADER;
goto exit;
}
if (consumed_second_stage_offset != second_stage_size) {
/* it is an error if there is leftover data after the last firmware header */
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__LEFTOVER_DATA_AFTER_LAST_FIRMWARE_HEADER;
goto exit;
}
/* the out params are all optional */
if (NULL != out_second_stage_header) {
*out_second_stage_header = second_stage_header;
}
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}
FW_BINARY_TYPE_t FIRMWARE_HEADER_UTILS__get_fw_binary_type(uint32_t binary_revision)
{
FW_BINARY_TYPE_t fw_binary_type = FW_BINARY_TYPE_INVALID;
// Remove dev flag before checking binary type
binary_revision &= ~(REVISION_DEV_FLAG_BIT_MASK);
if (REVISION_SECOND_STAGE_FLAG_BIT_MASK == (binary_revision & REVISION_SECOND_STAGE_FLAG_BIT_MASK)) {
fw_binary_type = FW_BINARY_TYPE_SECOND_STAGE_BOOT;
} else if (0 == (binary_revision & (REVISION_APP_CORE_FLAG_BIT_MASK))) {
fw_binary_type = FW_BINARY_TYPE_APP_FIRMWARE;
} else if (REVISION_APP_CORE_FLAG_BIT_MASK == (binary_revision & (REVISION_APP_CORE_FLAG_BIT_MASK))) {
fw_binary_type = FW_BINARY_TYPE_CORE_FIRMWARE;
} else {
fw_binary_type = FW_BINARY_TYPE_INVALID;
}
return fw_binary_type;
}
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__is_binary_being_downgraded(const firmware_version_t *new_binary_version,
const firmware_version_t *minimum_allowed_binary_version)
{
bool is_binary_being_downgraded =
// Check if minimum allowed binary's major is greater than new binary's major
(minimum_allowed_binary_version->firmware_major > new_binary_version->firmware_major) ||
// Check if minimum allowed binary's minor is greater than new binary's minor (If major is the same)
((minimum_allowed_binary_version->firmware_major == new_binary_version->firmware_major) &&
(minimum_allowed_binary_version->firmware_minor > new_binary_version->firmware_minor)) ||
// Check if minimum allowed binary's revision is greater than new binary's revision (If major and minor are the same)
((minimum_allowed_binary_version->firmware_major == new_binary_version->firmware_major) &&
(minimum_allowed_binary_version->firmware_minor == new_binary_version->firmware_minor) &&
(GET_REVISION_NUMBER_VALUE(minimum_allowed_binary_version->firmware_revision) >
(GET_REVISION_NUMBER_VALUE(new_binary_version->firmware_revision))));
return is_binary_being_downgraded;
}
HAILO_COMMON_STATUS_t FIRMWARE_HEADER_UTILS__validate_binary_version(const firmware_version_t *new_binary_version,
const firmware_version_t *minimum_allowed_binary_version,
FW_BINARY_TYPE_t fw_binary_type)
{
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
// Make sure downgrade is not executed
if (FIRMWARE_HEADER_UTILS__is_binary_being_downgraded(new_binary_version, minimum_allowed_binary_version)) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__DETECTED_PROHIBITED_DOWNGRADE_ATTEMPT;
goto exit;
}
if (FIRMWARE_HEADER_UTILS__get_fw_binary_type(new_binary_version->firmware_revision) != fw_binary_type) {
status = HAILO_STATUS__FIRMWARE_HEADER_UTILS__INVALID_BINARY_TYPE;
goto exit;
}
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}

View File

@@ -0,0 +1,135 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file firmware_status.c
* @brief Defines firmware status codes.
**/
#include <stdint.h>
#include "firmware_status.h"
#include <string.h>
#ifdef FIRMWARE_ARCH
#pragma pack(push, 1)
typedef struct {
const char *status_name;
uint32_t status_id;
} FIRMWARE_STATUS__status_record_t;
typedef struct {
const char *module_name;
uint32_t module_id;
} FIRMWARE_STATUS__module_record_t;
#pragma pack(pop)
#define FIRMWARE_STATUS_SECTION __attribute__((section(".firmware_statuses")))
#define FIRMWARE_MODULE__X(module) static const char module##_str[] FIRMWARE_STATUS_SECTION = #module;
#define FIRMWARE_STATUS__X(name) static const char name##_str[] FIRMWARE_STATUS_SECTION = #name;
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
const FIRMWARE_STATUS__module_record_t FIRMWARE_STATUS__module_records[] FIRMWARE_STATUS_SECTION = {
#define FIRMWARE_MODULE__X(module) { .module_id = module, .module_name = module##_str },
#define FIRMWARE_STATUS__X(name)
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
};
const FIRMWARE_STATUS__status_record_t FIRMWARE_STATUS__status_records[] FIRMWARE_STATUS_SECTION = {
#define FIRMWARE_MODULE__X(module)
#define FIRMWARE_STATUS__X(name) { .status_id = name, .status_name = name##_str },
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
};
#endif
#ifndef FIRMWARE_ARCH
static const char *FIRMWARE_STATUS__textual_format[] =
{
#define FIRMWARE_MODULE__X(module)
#define FIRMWARE_STATUS__X(name) #name,
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
};
/* The FIRMWARE_STATUS__textual_format array stores the strings in "absolute" order.
In order for us to know the absolute index of each status we store an array that for each module stores
the absolute index of it's first status.
This way we can compute the absolute index in O(1) time. */
#define HELPER_INDEX_NAME(__name) __HELPER_FIRMWARE_STATUS__##__name
/* the helper indices counts all module names and statuses.
the goal here is to be able to count how many statuses occured prior to each module.
we mark the module starts with the module__START elements, and in order
to calculate the number of statuses prior to the current module, we take the
module's module__START value, and subtract the number of __START element
of previous modules, which is the enum value of the module. */
typedef enum {
#define FIRMWARE_MODULE__X(module) HELPER_INDEX_NAME(module##__START),
#define FIRMWARE_STATUS__X(name) HELPER_INDEX_NAME(name),
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
} __FIRMWARE_STATUS__helper_indices_t;
static const uint32_t FIRMWARE_STATUS__absolute_module_indices[] = {
#define FIRMWARE_MODULE__X(module) HELPER_INDEX_NAME(module##__START) - module,
#define FIRMWARE_STATUS__X(name)
FIRMWARE_STATUS__VARIABLES
#undef FIRMWARE_STATUS__X
#undef FIRMWARE_MODULE__X
ARRAY_LENGTH(FIRMWARE_STATUS__textual_format)
};
HAILO_COMMON_STATUS_t FIRMWARE_STATUS__get_textual(FIRMWARE_STATUS_t fw_status, const char **text)
{
HAILO_COMMON_STATUS_t status = HAILO_COMMON_STATUS__UNINITIALIZED;
uint32_t module_id = 0;
uint32_t module_abs_index = 0;
uint32_t next_module_abs_index = 0;
uint32_t status_value = 0;
if (NULL == text) {
status = HAILO_STATUS__FIRMWARE_STATUS__NULL_ARGUMENT_PASSED;
goto exit;
}
if (FIRMWARE_STATUS__COMPONENT_ID != FIRMWARE_STATUS__COMPONENT_GET(fw_status)) {
status = HAILO_STATUS__FIRMWARE_STATUS__INVALID_COMPONENT_ID;
goto exit;
}
module_id = FIRMWARE_STATUS__MODULE_INDEX_GET(fw_status);
if (FIRMWARE_MODULE_COUNT <= module_id) {
status = HAILO_STATUS__FIRMWARE_STATUS__INVALID_MODULE_ID;
goto exit;
}
module_abs_index = FIRMWARE_STATUS__absolute_module_indices[module_id];
next_module_abs_index = FIRMWARE_STATUS__absolute_module_indices[module_id+1];
status_value = (uint32_t)FIRMWARE_STATUS__VALUE_GET(fw_status) - 1; /* status values start at 1 */
/* check status value is in the correct range */
if (status_value >= next_module_abs_index - module_abs_index) {
status = HAILO_STATUS__FIRMWARE_STATUS__INVALID_STATUS_VALUE;
goto exit;
}
*text = FIRMWARE_STATUS__textual_format[module_abs_index + status_value];
status = HAILO_COMMON_STATUS__SUCCESS;
exit:
return status;
}
#endif

291
common/src/md5.c Normal file
View File

@@ -0,0 +1,291 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* (This is a heavily cut-down "BSD license".)
*
* This differs from Colin Plumb's older public domain implementation in that
* no exactly 32-bit integer data type is required (any 32-bit or wider
* unsigned integer data type will do), there's no compile-time endianness
* configuration, and the function prototypes match OpenSSL's. No code from
* Colin Plumb's implementation has been reused; this comment merely compares
* the properties of the two independent implementations.
*
* The primary goals of this implementation are portability and ease of use.
* It is meant to be fast, but not as fast as possible. Some known
* optimizations are not included to reduce source code size and avoid
* compile-time configuration.
*/
#ifndef HAVE_OPENSSL
#include <string.h>
#include "md5.h"
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) (((x) ^ (y)) ^ (z))
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them in a
* properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned memory
* accesses is just an optimization. Nothing will break if it fails to detect
* a suitable architecture.
*
* Unfortunately, this optimization may be a C strict aliasing rules violation
* if the caller's data buffer has effective type that cannot be aliased by
* MD5_u32plus. In practice, this problem may occur if these MD5 routines are
* inlined into a calling function, or with future and dangerously advanced
* link-time optimizations. For the time being, keeping these MD5 routines in
* their own translation unit avoids the problem.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define GET(n) \
SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update the bit
* counters. There are no alignment requirements.
*/
static const void *body(MD5_CTX *ctx, const void *data, size_t size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, const void *data, size_t size)
{
MD5_u32plus saved_lo;
size_t used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
available = 64 - used;
if (size < available) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(size_t)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
#define OUT(dst, src) \
(dst)[0] = (unsigned char)(src); \
(dst)[1] = (unsigned char)((src) >> 8); \
(dst)[2] = (unsigned char)((src) >> 16); \
(dst)[3] = (unsigned char)((src) >> 24);
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8) {
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
OUT(&ctx->buffer[56], ctx->lo)
OUT(&ctx->buffer[60], ctx->hi)
body(ctx, ctx->buffer, 64);
OUT(&result[0], ctx->a)
OUT(&result[4], ctx->b)
OUT(&result[8], ctx->c)
OUT(&result[12], ctx->d)
memset(ctx, 0, sizeof(*ctx));
}
#endif