Commit 8a43c83f authored by Ohad Sharabi's avatar Ohad Sharabi Committed by Oded Gabbay

habanalabs: load boot fit to device

Implementing dynamic boot fit image load to the device.
Note that some necessary adjustment were added to the static loader as
well so that both loaders can co-exist.
as this is not the final FW load stage the dynamic FW load is still
forced to be non functional.
Signed-off-by: default avatarOhad Sharabi <osharabi@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent b8e785c5
......@@ -846,6 +846,8 @@ struct pci_mem_region {
* struct static_fw_load_mgr - static FW load manager
* @preboot_version_max_off: max offset to preboot version
* @boot_fit_version_max_off: max offset to boot fit version
* @kmd_msg_to_cpu_reg: register address for KDM->CPU messages
* @cpu_cmd_status_to_host_reg: register address for CPU command status response
* @cpu_boot_status_reg: boot status register
* @cpu_boot_dev_status_reg: boot device status register
* @boot_err0_reg: boot error register
......@@ -856,6 +858,8 @@ struct pci_mem_region {
struct static_fw_load_mgr {
u64 preboot_version_max_off;
u64 boot_fit_version_max_off;
u32 kmd_msg_to_cpu_reg;
u32 cpu_cmd_status_to_host_reg;
u32 cpu_boot_status_reg;
u32 cpu_boot_dev_status_reg;
u32 boot_err0_reg;
......@@ -864,37 +868,68 @@ struct static_fw_load_mgr {
u32 sram_offset_mask;
};
/**
* struct fw_response - FW response to LKD command
* @ram_offset: descriptor offset into the RAM
* @ram_type: RAM type containing the descriptor (SRAM/DRAM)
* @status: command status
*/
struct fw_response {
u32 ram_offset;
u8 ram_type;
u8 status;
};
/**
* struct dynamic_fw_load_mgr - dynamic FW load manager
* TODO: currently empty, will be filled once boot stages implementation will
* progress.
* @response: FW to LKD response
* @comm_desc: the communication descriptor with FW
* @image_region: region to copy the FW image to
* @fw_image_size: FW image size
*/
struct dynamic_fw_load_mgr {
struct fw_response response;
struct lkd_fw_comms_desc comm_desc;
struct pci_mem_region *image_region;
size_t fw_image_size;
};
/**
* struct fw_image_props - properties of FW image
* @image_name: name of the image
* @src_off: offset in src FW to copy from
* @copy_size: amount of bytes to copy (0 to copy the whole binary)
*/
struct fw_image_props {
char *image_name;
u32 src_off;
u32 copy_size;
};
/**
* struct fw_load_mgr - manager FW loading process
* @kmd_msg_to_cpu_reg: register address for KDM->CPU messages
* @cpu_cmd_status_to_host_reg: register address for CPU command status response
* @dynamic_loader: specific structure for dynamic load
* @static_loader: specific structure for static load
* @boot_fit_img: boot fit image properties
* @linux_img: linux image properties
* @cpu_timeout: CPU response timeout in usec
* @boot_fit_timeout: Boot fit load timeout in usec
* @skip_bmc: should BMC be skipped
* @sram_bar_id: SRAM bar ID
* @static_loader: specific structure for static load
* @dynamic_loader: specific structure for dynamic load
* @dram_bar_id: DRAM bar ID
*/
struct fw_load_mgr {
u32 kmd_msg_to_cpu_reg;
u32 cpu_cmd_status_to_host_reg;
union {
struct dynamic_fw_load_mgr dynamic_loader;
struct static_fw_load_mgr static_loader;
};
struct fw_image_props boot_fit_img;
struct fw_image_props linux_img;
u32 cpu_timeout;
u32 boot_fit_timeout;
u8 skip_bmc;
u8 sram_bar_id;
union {
struct static_fw_load_mgr static_loader;
struct dynamic_fw_load_mgr dynamic_loader;
};
u8 dram_bar_id;
};
/**
......
......@@ -3732,7 +3732,23 @@ static int gaudi_load_boot_fit_to_device(struct hl_device *hdev)
static void gaudi_init_dynamic_firmware_loader(struct hl_device *hdev)
{
struct dynamic_fw_load_mgr *dynamic_loader;
struct cpu_dyn_regs *dyn_regs;
dynamic_loader = &hdev->fw_loader.dynamic_loader;
/*
* here we update initial values for few specific dynamic regs (as
* before reading the first descriptor from FW those value has to be
* hard-coded) in later stages of the protocol those values will be
* updated automatically by reading the FW descriptor so data there
* will always be up-to-date
*/
dyn_regs = &dynamic_loader->comm_desc.cpu_dyn_regs;
dyn_regs->kmd_msg_to_cpu =
cpu_to_le32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU);
dyn_regs->cpu_cmd_status_to_host =
cpu_to_le32(mmCPU_CMD_STATUS_TO_HOST);
}
static void gaudi_init_static_firmware_loader(struct hl_device *hdev)
......@@ -3743,6 +3759,8 @@ static void gaudi_init_static_firmware_loader(struct hl_device *hdev)
static_loader->preboot_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
static_loader->boot_fit_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
static_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
static_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
static_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
static_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
static_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
......@@ -3757,12 +3775,13 @@ static void gaudi_init_firmware_loader(struct hl_device *hdev)
struct fw_load_mgr *fw_loader = &hdev->fw_loader;
/* fill common fields */
fw_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
fw_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
fw_loader->boot_fit_img.image_name = GAUDI_BOOT_FIT_FILE;
fw_loader->linux_img.image_name = GAUDI_LINUX_FW_FILE;
fw_loader->cpu_timeout = GAUDI_CPU_TIMEOUT_USEC;
fw_loader->boot_fit_timeout = GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC;
fw_loader->skip_bmc = !hdev->bmc_enable;
fw_loader->sram_bar_id = SRAM_BAR_ID;
fw_loader->dram_bar_id = HBM_BAR_ID;
if (prop->dynamic_fw_load)
gaudi_init_dynamic_firmware_loader(hdev);
......
......@@ -2435,7 +2435,23 @@ static int goya_load_boot_fit_to_device(struct hl_device *hdev)
static void goya_init_dynamic_firmware_loader(struct hl_device *hdev)
{
struct dynamic_fw_load_mgr *dynamic_loader;
struct cpu_dyn_regs *dyn_regs;
dynamic_loader = &hdev->fw_loader.dynamic_loader;
/*
* here we update initial values for few specific dynamic regs (as
* before reading the first descriptor from FW those value has to be
* hard-coded) in later stages of the protocol those values will be
* updated automatically by reading the FW descriptor so data there
* will always be up-to-date
*/
dyn_regs = &dynamic_loader->comm_desc.cpu_dyn_regs;
dyn_regs->kmd_msg_to_cpu =
cpu_to_le32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU);
dyn_regs->cpu_cmd_status_to_host =
cpu_to_le32(mmCPU_CMD_STATUS_TO_HOST);
}
static void goya_init_static_firmware_loader(struct hl_device *hdev)
......@@ -2446,6 +2462,8 @@ static void goya_init_static_firmware_loader(struct hl_device *hdev)
static_loader->preboot_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
static_loader->boot_fit_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
static_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
static_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
static_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
static_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
static_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
......@@ -2460,12 +2478,13 @@ static void goya_init_firmware_loader(struct hl_device *hdev)
struct fw_load_mgr *fw_loader = &hdev->fw_loader;
/* fill common fields */
fw_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
fw_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
fw_loader->boot_fit_img.image_name = GOYA_BOOT_FIT_FILE;
fw_loader->linux_img.image_name = GOYA_LINUX_FW_FILE;
fw_loader->cpu_timeout = GOYA_CPU_TIMEOUT_USEC;
fw_loader->boot_fit_timeout = GOYA_BOOT_FIT_REQ_TIMEOUT_USEC;
fw_loader->skip_bmc = false;
fw_loader->sram_bar_id = SRAM_CFG_BAR_ID;
fw_loader->dram_bar_id = DDR_BAR_ID;
if (prop->dynamic_fw_load)
goya_init_dynamic_firmware_loader(hdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment