return -EINVAL;
 }
 
-int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
-                       u32 msg_to_cpu_reg, u32 cpu_msg_status_reg,
-                       u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
-                       bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout)
+int hl_fw_init_cpu(struct hl_device *hdev)
 {
+       u32 cpu_msg_status_reg, cpu_timeout, msg_to_cpu_reg, status;
+       u32 cpu_boot_status_reg, cpu_security_boot_status_reg;
        struct asic_fixed_properties *prop = &hdev->asic_prop;
-       u32 status;
+       struct fw_load_mgr *fw_loader;
        int rc;
 
        if (!(hdev->fw_components & FW_TYPE_BOOT_CPU))
                return 0;
 
+       /* init loader parameters */
+       hdev->asic_funcs->init_firmware_loader(hdev);
+       fw_loader = &hdev->fw_loader;
+       cpu_security_boot_status_reg = fw_loader->cpu_boot_status_reg;
+       cpu_msg_status_reg = fw_loader->cpu_cmd_status_to_host_reg;
+       cpu_boot_status_reg = fw_loader->cpu_boot_status_reg;
+       msg_to_cpu_reg = fw_loader->kmd_msg_to_cpu_reg;
+       cpu_timeout = fw_loader->cpu_timeout;
+
        dev_info(hdev->dev, "Going to wait for device boot (up to %lds)\n",
                cpu_timeout / USEC_PER_SEC);
 
                status,
                status == CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT,
                10000,
-               boot_fit_timeout);
+               fw_loader->boot_fit_timeout);
 
        if (rc) {
                dev_dbg(hdev->dev,
                        status,
                        status == CPU_MSG_OK,
                        10000,
-                       boot_fit_timeout);
+                       fw_loader->boot_fit_timeout);
 
                if (rc) {
                        dev_err(hdev->dev,
        if (rc)
                goto out;
 
-       if (skip_bmc) {
+       if (fw_loader->skip_bmc) {
                WREG32(msg_to_cpu_reg, KMD_MSG_SKIP_BMC);
 
                rc = hl_poll_timeout(
                goto out;
        }
 
-       rc = fw_read_errors(hdev, boot_err0_reg, cpu_security_boot_status_reg);
+       rc = fw_read_errors(hdev, fw_loader->boot_err0_reg,
+                                       cpu_security_boot_status_reg);
        if (rc)
                return rc;
 
        return 0;
 
 out:
-       fw_read_errors(hdev, boot_err0_reg, cpu_security_boot_status_reg);
+       fw_read_errors(hdev, fw_loader->boot_err0_reg,
+                                       cpu_security_boot_status_reg);
 
        return rc;
 }
 
        DIV_SEL_DIVIDED_PLL = 3,
 };
 
+/**
+ * struct fw_load_mgr - manager FW loading process
+ * @kmd_msg_to_cpu_reg: register address for KMD->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
+ * @cpu_timeout: CPU response timeout in usec
+ * @boot_fit_timeout: Boot fit load timeout in usec
+ * @skip_bmc: should BMC be skipped
+ */
+struct fw_load_mgr {
+       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;
+       u32 cpu_timeout;
+       u32 boot_fit_timeout;
+       u8 skip_bmc;
+};
+
 /**
  * struct hl_asic_funcs - ASIC specific functions that are can be called from
  *                        common code.
  * @get_msi_info: Retrieve asic-specific MSI ID of the f/w async event
  * @map_pll_idx_to_fw_idx: convert driver specific per asic PLL index to
  *                         generic f/w compatible PLL Indexes
+ *@init_firmware_loader: initialize data for FW loader.
  */
 struct hl_asic_funcs {
        int (*early_init)(struct hl_device *hdev);
        void (*enable_events_from_fw)(struct hl_device *hdev);
        void (*get_msi_info)(u32 *table);
        int (*map_pll_idx_to_fw_idx)(u32 pll_idx);
+       void (*init_firmware_loader)(struct hl_device *hdev);
 };
 
 
  * @aggregated_cs_counters: aggregated cs counters among all contexts
  * @mmu_priv: device-specific MMU data.
  * @mmu_func: device-related MMU functions.
+ * @fw_loader: FW loader manager.
  * @dram_used_mem: current DRAM memory consumption.
  * @timeout_jiffies: device CS timeout value.
  * @max_power: the max power of the device, as configured by the sysadmin. This
        struct hl_mmu_priv              mmu_priv;
        struct hl_mmu_funcs             mmu_func[MMU_NUM_PGT_LOCATIONS];
 
+       struct fw_load_mgr              fw_loader;
+
        atomic64_t                      dram_used_mem;
        u64                             timeout_jiffies;
        u64                             max_power;
 int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u32 pll_index,
                u16 *pll_freq_arr);
 int hl_fw_cpucp_power_get(struct hl_device *hdev, u64 *power);
-int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
-                       u32 msg_to_cpu_reg, u32 cpu_msg_status_reg,
-                       u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
-                       bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout);
+int hl_fw_init_cpu(struct hl_device *hdev);
 int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
                u32 cpu_boot_caps_reg, u32 boot_err0_reg,
                u32 timeout);
 
        return 0;
 }
 
+static void gaudi_init_firmware_loader(struct hl_device *hdev)
+{
+       struct fw_load_mgr *fw_loader = &hdev->fw_loader;
+
+       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->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->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
+       fw_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
+       fw_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
+}
+
 static int gaudi_init_cpu(struct hl_device *hdev)
 {
        struct gaudi_device *gaudi = hdev->asic_specific;
        if (hdev->asic_prop.fw_security_disabled)
                WREG32(mmCPU_IF_CPU_MSB_ADDR, hdev->cpu_pci_msb_addr);
 
-       rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
-                       mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU,
-                       mmCPU_CMD_STATUS_TO_HOST,
-                       mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0,
-                       !hdev->bmc_enable, GAUDI_CPU_TIMEOUT_USEC,
-                       GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC);
+       rc = hl_fw_init_cpu(hdev);
 
        if (rc)
                return rc;
        .get_hw_block_id = gaudi_get_hw_block_id,
        .hw_block_mmap = gaudi_block_mmap,
        .enable_events_from_fw = gaudi_enable_events_from_fw,
-       .map_pll_idx_to_fw_idx = gaudi_map_pll_idx_to_fw_idx
+       .map_pll_idx_to_fw_idx = gaudi_map_pll_idx_to_fw_idx,
+       .init_firmware_loader = gaudi_init_firmware_loader,
 };
 
 /**
 
        return 0;
 }
 
+static void goya_init_firmware_loader(struct hl_device *hdev)
+{
+       struct fw_load_mgr *fw_loader = &hdev->fw_loader;
+
+       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->cpu_timeout = GOYA_CPU_TIMEOUT_USEC;
+       fw_loader->boot_fit_timeout = GOYA_BOOT_FIT_REQ_TIMEOUT_USEC;
+       fw_loader->skip_bmc = false;
+       fw_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
+       fw_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
+       fw_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
+}
+
 static int goya_init_cpu(struct hl_device *hdev)
 {
        struct goya_device *goya = hdev->asic_specific;
                return -EIO;
        }
 
-       rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
-                       mmPSOC_GLOBAL_CONF_UBOOT_MAGIC,
-                       mmCPU_CMD_STATUS_TO_HOST,
-                       mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0,
-                       false, GOYA_CPU_TIMEOUT_USEC,
-                       GOYA_BOOT_FIT_REQ_TIMEOUT_USEC);
+       rc = hl_fw_init_cpu(hdev);
 
        if (rc)
                return rc;
        .get_hw_block_id = goya_get_hw_block_id,
        .hw_block_mmap = goya_block_mmap,
        .enable_events_from_fw = goya_enable_events_from_fw,
-       .map_pll_idx_to_fw_idx = goya_map_pll_idx_to_fw_idx
+       .map_pll_idx_to_fw_idx = goya_map_pll_idx_to_fw_idx,
+       .init_firmware_loader = goya_init_firmware_loader
 };
 
 /*