/* Check if current bios is an ATOM BIOS. *ReturntrueifitisATOMBIOS.Otherwise,returnfalse.
*/ staticbool check_atom_bios(struct amdgpu_device *adev, size_t size)
{
uint16_t tmp, bios_header_start;
uint8_t *bios = adev->bios;
if (!bios || size < 0x49) {
dev_dbg(adev->dev, "VBIOS mem is null or mem size is wrong\n"); returnfalse;
}
adev->bios = NULL; /* XXX: some cards may return 0 for rom size? ddx has a workaround */
bios = pci_map_rom(adev->pdev, &size); if (!bios) returnfalse;
if ((!AMD_IS_VALID_VBIOS(header)) ||
memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET],
AMD_VBIOS_SIGNATURE,
strlen(AMD_VBIOS_SIGNATURE)) != 0) returnfalse;
/* valid vbios, go on */
len = AMD_VBIOS_LENGTH(header);
len = ALIGN(len, 4);
adev->bios = kmalloc(len, GFP_KERNEL); if (!adev->bios) {
DRM_ERROR("no memory to allocate for BIOS\n"); returnfalse;
}
adev->bios_size = len;
if (!check_atom_bios(adev, romlen)) goto free_bios;
adev->bios_size = romlen;
returntrue;
free_bios:
amdgpu_bios_release(adev);
returnfalse;
}
#ifdef CONFIG_ACPI /* ATRM is used to get the BIOS on the discrete cards in *dual-gpusystems.
*/ /* retrieve the ROM in 4k blocks */ #define ATRM_BIOS_PAGE 4096 /** *amdgpu_atrm_call-fetchachunkofthevbios * *@atrm_handle:acpiATRMhandle *@bios:vbiosimagepointer *@offset:offsetofvbiosimagedatatofetch *@len:lengthofvbiosimagedatatofetch * *ExecutesATRMtofetchachunkofthediscrete *vbiosimageonPXsystems(allasics). *Returnsthelengthofthebufferfetched.
*/ staticint amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios, int offset, int len)
{
acpi_status status; union acpi_object atrm_arg_elements[2], *obj; struct acpi_object_list atrm_arg; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
staticbool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
{ int ret; int size = 256 * 1024; int i; struct pci_dev *pdev = NULL;
acpi_handle dhandle, atrm_handle;
acpi_status status; bool found = false;
/* ATRM is for on-platform devices only */ if (dev_is_removable(&adev->pdev->dev)) returnfalse;
while ((pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) { if ((pdev->class != PCI_CLASS_DISPLAY_VGA << 8) &&
(pdev->class != PCI_CLASS_DISPLAY_OTHER << 8)) continue;
dhandle = ACPI_HANDLE(&pdev->dev); if (!dhandle) continue;
status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); if (ACPI_SUCCESS(status)) {
found = true; break;
}
}
if (!found) returnfalse;
pci_dev_put(pdev);
adev->bios = kmalloc(size, GFP_KERNEL); if (!adev->bios) {
dev_err(adev->dev, "Unable to allocate bios\n"); returnfalse;
}
for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
ret = amdgpu_atrm_call(atrm_handle,
adev->bios,
(i * ATRM_BIOS_PAGE),
ATRM_BIOS_PAGE); if (ret < ATRM_BIOS_PAGE) break;
}
if (adev->flags & AMD_IS_APU)
found = amdgpu_get_bios_apu(adev); else
found = amdgpu_get_bios_dgpu(adev);
if (found)
adev->is_atom_fw = adev->asic_type >= CHIP_VEGA10;
return found;
}
/* helper function for soc15 and onwards to read bios from rom */ bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
u8 *bios, u32 length_bytes)
{
u32 *dw_ptr;
u32 i, length_dw;
u32 rom_offset;
u32 rom_index_offset;
u32 rom_data_offset;
if (bios == NULL) returnfalse; if (length_bytes == 0) returnfalse; /* APU vbios image is part of sbios image */ if (adev->flags & AMD_IS_APU) returnfalse; if (!adev->smuio.funcs ||
!adev->smuio.funcs->get_rom_index_offset ||
!adev->smuio.funcs->get_rom_data_offset) returnfalse;
/* set rom index to rom_offset */
WREG32(rom_index_offset, rom_offset); /* read out the rom data */ for (i = 0; i < length_dw; i++)
dw_ptr[i] = RREG32(rom_data_offset);
returntrue;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-03)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.