habanalabs/gaudi: skip iATU if F/W security is enabled
As part of the securing GAUDI, the F/W will configure the PCI iATU regions. If the driver identifies a secured PCI ID, it will know to skip iATU configuration in a very early stage. Signed-off-by: Ofir Bitton <obitton@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
e5042a6fa6
commit
41f458f205
|
@ -445,6 +445,7 @@ struct hl_mmu_properties {
|
|||
* @dram_supports_virtual_memory: is there an MMU towards the DRAM
|
||||
* @hard_reset_done_by_fw: true if firmware is handling hard reset flow
|
||||
* @num_functional_hbms: number of functional HBMs in each DCORE.
|
||||
* @iatu_done_by_fw: true if iATU configuration is being done by FW.
|
||||
*/
|
||||
struct asic_fixed_properties {
|
||||
struct hw_queue_properties *hw_queues_props;
|
||||
|
@ -508,6 +509,7 @@ struct asic_fixed_properties {
|
|||
u8 dram_supports_virtual_memory;
|
||||
u8 hard_reset_done_by_fw;
|
||||
u8 num_functional_hbms;
|
||||
u8 iatu_done_by_fw;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2400,6 +2402,7 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
|
|||
|
||||
int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
|
||||
bool is_wc[3]);
|
||||
int hl_pci_elbi_read(struct hl_device *hdev, u64 addr, u32 *data);
|
||||
int hl_pci_iatu_write(struct hl_device *hdev, u32 addr, u32 data);
|
||||
int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region,
|
||||
struct hl_inbound_pci_region *pci_region);
|
||||
|
|
|
@ -85,6 +85,58 @@ static void hl_pci_bars_unmap(struct hl_device *hdev)
|
|||
pci_release_regions(pdev);
|
||||
}
|
||||
|
||||
int hl_pci_elbi_read(struct hl_device *hdev, u64 addr, u32 *data)
|
||||
{
|
||||
struct pci_dev *pdev = hdev->pdev;
|
||||
ktime_t timeout;
|
||||
u64 msec;
|
||||
u32 val;
|
||||
|
||||
if (hdev->pldm)
|
||||
msec = HL_PLDM_PCI_ELBI_TIMEOUT_MSEC;
|
||||
else
|
||||
msec = HL_PCI_ELBI_TIMEOUT_MSEC;
|
||||
|
||||
/* Clear previous status */
|
||||
pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, 0);
|
||||
|
||||
pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_ADDR, (u32) addr);
|
||||
pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_CTRL, 0);
|
||||
|
||||
timeout = ktime_add_ms(ktime_get(), msec);
|
||||
for (;;) {
|
||||
pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, &val);
|
||||
if (val & PCI_CONFIG_ELBI_STS_MASK)
|
||||
break;
|
||||
if (ktime_compare(ktime_get(), timeout) > 0) {
|
||||
pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS,
|
||||
&val);
|
||||
break;
|
||||
}
|
||||
|
||||
usleep_range(300, 500);
|
||||
}
|
||||
|
||||
if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE) {
|
||||
pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_DATA, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (val & PCI_CONFIG_ELBI_STS_ERR) {
|
||||
dev_err(hdev->dev, "Error reading from ELBI\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!(val & PCI_CONFIG_ELBI_STS_MASK)) {
|
||||
dev_err(hdev->dev, "ELBI read didn't finish in time\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dev_err(hdev->dev, "ELBI read has undefined bits in status\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* hl_pci_elbi_write() - Write through the ELBI interface.
|
||||
* @hdev: Pointer to hl_device structure.
|
||||
|
|
|
@ -629,6 +629,11 @@ static int gaudi_init_iatu(struct hl_device *hdev)
|
|||
struct hl_outbound_pci_region outbound_region;
|
||||
int rc;
|
||||
|
||||
if (hdev->asic_prop.iatu_done_by_fw) {
|
||||
hdev->asic_funcs->set_dma_mask_from_fw(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Inbound Region 0 - Bar 0 - Point to SRAM + CFG */
|
||||
inbound_region.mode = PCI_BAR_MATCH_MODE;
|
||||
inbound_region.bar = SRAM_BAR_ID;
|
||||
|
@ -673,6 +678,7 @@ static int gaudi_early_init(struct hl_device *hdev)
|
|||
{
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
struct pci_dev *pdev = hdev->pdev;
|
||||
u32 fw_boot_status;
|
||||
int rc;
|
||||
|
||||
rc = gaudi_get_fixed_properties(hdev);
|
||||
|
@ -706,6 +712,23 @@ static int gaudi_early_init(struct hl_device *hdev)
|
|||
|
||||
prop->dram_pci_bar_size = pci_resource_len(pdev, HBM_BAR_ID);
|
||||
|
||||
/* If FW security is enabled at this point it means no access to ELBI */
|
||||
if (!hdev->asic_prop.fw_security_disabled) {
|
||||
hdev->asic_prop.iatu_done_by_fw = true;
|
||||
goto pci_init;
|
||||
}
|
||||
|
||||
rc = hl_pci_elbi_read(hdev, CFG_BASE + mmCPU_BOOT_DEV_STS0,
|
||||
&fw_boot_status);
|
||||
if (rc)
|
||||
goto free_queue_props;
|
||||
|
||||
/* Check whether FW is configuring iATU */
|
||||
if ((fw_boot_status & CPU_BOOT_DEV_STS0_ENABLED) &&
|
||||
(fw_boot_status & CPU_BOOT_DEV_STS0_FW_IATU_CONF_EN))
|
||||
hdev->asic_prop.iatu_done_by_fw = true;
|
||||
|
||||
pci_init:
|
||||
rc = hl_pci_init(hdev);
|
||||
if (rc)
|
||||
goto free_queue_props;
|
||||
|
|
|
@ -555,6 +555,11 @@ static int goya_init_iatu(struct hl_device *hdev)
|
|||
struct hl_outbound_pci_region outbound_region;
|
||||
int rc;
|
||||
|
||||
if (hdev->asic_prop.iatu_done_by_fw) {
|
||||
hdev->asic_funcs->set_dma_mask_from_fw(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Inbound Region 0 - Bar 0 - Point to SRAM and CFG */
|
||||
inbound_region.mode = PCI_BAR_MATCH_MODE;
|
||||
inbound_region.bar = SRAM_CFG_BAR_ID;
|
||||
|
@ -602,7 +607,7 @@ static int goya_early_init(struct hl_device *hdev)
|
|||
{
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
struct pci_dev *pdev = hdev->pdev;
|
||||
u32 val;
|
||||
u32 fw_boot_status, val;
|
||||
int rc;
|
||||
|
||||
rc = goya_get_fixed_properties(hdev);
|
||||
|
@ -636,6 +641,23 @@ static int goya_early_init(struct hl_device *hdev)
|
|||
|
||||
prop->dram_pci_bar_size = pci_resource_len(pdev, DDR_BAR_ID);
|
||||
|
||||
/* If FW security is enabled at this point it means no access to ELBI */
|
||||
if (!hdev->asic_prop.fw_security_disabled) {
|
||||
hdev->asic_prop.iatu_done_by_fw = true;
|
||||
goto pci_init;
|
||||
}
|
||||
|
||||
rc = hl_pci_elbi_read(hdev, CFG_BASE + mmCPU_BOOT_DEV_STS0,
|
||||
&fw_boot_status);
|
||||
if (rc)
|
||||
goto free_queue_props;
|
||||
|
||||
/* Check whether FW is configuring iATU */
|
||||
if ((fw_boot_status & CPU_BOOT_DEV_STS0_ENABLED) &&
|
||||
(fw_boot_status & CPU_BOOT_DEV_STS0_FW_IATU_CONF_EN))
|
||||
hdev->asic_prop.iatu_done_by_fw = true;
|
||||
|
||||
pci_init:
|
||||
rc = hl_pci_init(hdev);
|
||||
if (rc)
|
||||
goto free_queue_props;
|
||||
|
|
Loading…
Reference in New Issue