mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
drm/amdgpu: Use new read bios from rom callback
Read the vbios directly from the rom. In some cases, e.g., virtualization, the rom is not available via the BAR or other means. Access it directly. This is an updated version of Monks original patch which uses family specific callbacks and unifies some of the validation checking. Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> Signed-off-by: Monk Liu <Monk.Liu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
95addb2ae0
commit
f930b2e862
1 changed files with 50 additions and 8 deletions
|
@ -35,6 +35,13 @@
|
|||
* BIOS.
|
||||
*/
|
||||
|
||||
#define AMD_VBIOS_SIGNATURE " 761295520"
|
||||
#define AMD_VBIOS_SIGNATURE_OFFSET 0x30
|
||||
#define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE)
|
||||
#define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE)
|
||||
#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA)
|
||||
#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9)
|
||||
|
||||
/* If you boot an IGP board with a discrete card as the primary,
|
||||
* the IGP rom is not accessible via the rom bar as the IGP rom is
|
||||
* part of the system bios. On boot, the system bios puts a
|
||||
|
@ -58,7 +65,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||
if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
|
||||
iounmap(bios);
|
||||
return false;
|
||||
}
|
||||
|
@ -74,7 +81,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
|
|||
|
||||
bool amdgpu_read_bios(struct amdgpu_device *adev)
|
||||
{
|
||||
uint8_t __iomem *bios, val1, val2;
|
||||
uint8_t __iomem *bios, val[2];
|
||||
size_t size;
|
||||
|
||||
adev->bios = NULL;
|
||||
|
@ -84,10 +91,10 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
|
|||
return false;
|
||||
}
|
||||
|
||||
val1 = readb(&bios[0]);
|
||||
val2 = readb(&bios[1]);
|
||||
val[0] = readb(&bios[0]);
|
||||
val[1] = readb(&bios[1]);
|
||||
|
||||
if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
|
||||
if (size == 0 || !AMD_IS_VALID_VBIOS(val)) {
|
||||
pci_unmap_rom(adev->pdev, bios);
|
||||
return false;
|
||||
}
|
||||
|
@ -101,6 +108,38 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
|
||||
{
|
||||
u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0};
|
||||
int len;
|
||||
|
||||
if (!adev->asic_funcs->read_bios_from_rom)
|
||||
return false;
|
||||
|
||||
/* validate VBIOS signature */
|
||||
if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false)
|
||||
return false;
|
||||
header[AMD_VBIOS_SIGNATURE_END] = 0;
|
||||
|
||||
if ((!AMD_IS_VALID_VBIOS(header)) ||
|
||||
0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET],
|
||||
AMD_VBIOS_SIGNATURE,
|
||||
strlen(AMD_VBIOS_SIGNATURE)))
|
||||
return false;
|
||||
|
||||
/* 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");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read complete BIOS */
|
||||
return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
|
||||
}
|
||||
|
||||
static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
|
||||
{
|
||||
uint8_t __iomem *bios;
|
||||
|
@ -113,7 +152,7 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||
if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
|
||||
return false;
|
||||
}
|
||||
adev->bios = kmemdup(bios, size, GFP_KERNEL);
|
||||
|
@ -230,7 +269,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
|
|||
break;
|
||||
}
|
||||
|
||||
if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
|
||||
if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) {
|
||||
kfree(adev->bios);
|
||||
return false;
|
||||
}
|
||||
|
@ -319,6 +358,9 @@ bool amdgpu_get_bios(struct amdgpu_device *adev)
|
|||
r = igp_read_bios_from_vram(adev);
|
||||
if (r == false)
|
||||
r = amdgpu_read_bios(adev);
|
||||
if (r == false) {
|
||||
r = amdgpu_read_bios_from_rom(adev);
|
||||
}
|
||||
if (r == false) {
|
||||
r = amdgpu_read_disabled_bios(adev);
|
||||
}
|
||||
|
@ -330,7 +372,7 @@ bool amdgpu_get_bios(struct amdgpu_device *adev)
|
|||
adev->bios = NULL;
|
||||
return false;
|
||||
}
|
||||
if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
|
||||
if (!AMD_IS_VALID_VBIOS(adev->bios)) {
|
||||
printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]);
|
||||
goto free_bios;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue