diff options
Diffstat (limited to 'kernel/gsp_phys_vbios.c')
| -rw-r--r-- | kernel/gsp_phys_vbios.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/kernel/gsp_phys_vbios.c b/kernel/gsp_phys_vbios.c index fa7849d..33fb389 100644 --- a/kernel/gsp_phys_vbios.c +++ b/kernel/gsp_phys_vbios.c @@ -61,8 +61,6 @@ #define GSP_PHYS_BIT_TOKEN_ENTRIES_OFF 10 #define GSP_PHYS_BIT_TOKEN_BIOSDATA 0x42 #define GSP_PHYS_BIT_TOKEN_FALCON_DATA 0x70 -#define GSP_PHYS_BIT_TOKEN_SIZE_6 6 -#define GSP_PHYS_BIT_TOKEN_SIZE_8 8 #define GSP_PHYS_BIT_BIOSDATA_SIZE_MIN 5 #define GSP_PHYS_BIT_FALCON_DATA_V2_SIZE_MIN 4 #define GSP_PHYS_FALCON_UCODE_TABLE_VERSION 1 @@ -155,12 +153,15 @@ static bool gsp_phys_img_read(const struct gsp_phys_vbios *img, u32 offset, * 3 stores the flash-status offset at the total-data-size offset and the ROM * directory 4096 bytes after that. */ -static int gsp_phys_vbios_find_pci_header(void __iomem *bar0, u32 *pci_offset) +static int gsp_phys_vbios_find_pci_header(void __iomem *bar0, u32 *pci_offset, + u32 *ifr_version) { u32 fixed0, fixed1, fixed2; u32 image_offset = 0; u32 data_size, flash_status, directory_sig, version; + *ifr_version = 0; + if (!gsp_phys_prom_read32(bar0, 0, &fixed0) || !gsp_phys_prom_read32(bar0, 4, &fixed1) || !gsp_phys_prom_read32(bar0, 8, &fixed2)) @@ -223,6 +224,7 @@ static int gsp_phys_vbios_find_pci_header(void __iomem *bar0, u32 *pci_offset) return -EINVAL; } + *ifr_version = version; *pci_offset = image_offset; return 0; } @@ -407,7 +409,7 @@ int gsp_phys_vbios_read(struct gsp_phys_vbios *img, struct pci_dev *pdev, void __iomem *bar0) { u32 pci_offset = 0, bios_size = 0, expansion_rom_offset = 0; - u32 rom_sig, rom_end; + u32 rom_sig, rom_end, ifr_version = 0; int ret; if (!img || !bar0) @@ -421,7 +423,8 @@ int gsp_phys_vbios_read(struct gsp_phys_vbios *img, struct pci_dev *pdev, if (rom_sig != GSP_PHYS_ROM_SIG_STD && rom_sig != GSP_PHYS_ROM_SIG_NV && rom_sig != GSP_PHYS_ROM_SIG_NV2) { - ret = gsp_phys_vbios_find_pci_header(bar0, &pci_offset); + ret = gsp_phys_vbios_find_pci_header(bar0, &pci_offset, + &ifr_version); if (ret) return ret; @@ -456,10 +459,12 @@ int gsp_phys_vbios_read(struct gsp_phys_vbios *img, struct pci_dev *pdev, if (ret) return ret; + img->ifr_version = ifr_version; img->expansion_rom_offset = expansion_rom_offset; - pr_info("gsp-phys-vbios: ROM on %s: pciOffset=0x%x size=0x%x expansionRomOffset=0x%x\n", - pci_name(pdev), pci_offset, bios_size, expansion_rom_offset); + pr_info("gsp-phys-vbios: ROM on %s: pciOffset=0x%x size=0x%x expansionRomOffset=0x%x IFRversion=%u\n", + pci_name(pdev), pci_offset, bios_size, expansion_rom_offset, + ifr_version); return 0; } @@ -626,7 +631,7 @@ static int gsp_phys_vbios_parse_desc(const struct gsp_phys_vbios *img, * entries for the requested FWSEC application. Also reports the combined * VBIOS version from the BIOSDATA token when present. */ -int gsp_phys_vbios_parse_fwsec(const struct gsp_phys_vbios *img, +int gsp_phys_vbios_parse_fwsec(struct gsp_phys_vbios *img, bool use_debug_app, struct gsp_phys_fwsec_desc *desc) { @@ -654,8 +659,16 @@ int gsp_phys_vbios_parse_fwsec(const struct gsp_phys_vbios *img, bit_addr); return -EINVAL; } + + img->bit_addr = bit_addr; + img->bit_token_size = token_size; + img->bit_token_entries = token_entries; + pr_info("gsp-phys-vbios: BIT header at 0x%x headerSize=%u tokenSize=%u tokens=%u\n", bit_addr, header_size, token_size, token_entries); + pr_info("gsp-phys-vbios: BIT token type: %u-byte tokens (%s)\n", + token_size, token_size >= GSP_PHYS_BIT_TOKEN_SIZE_8 ? + "DataPtr u32 at offset 4" : "DataPtr u16 at offset 4"); if (token_size < GSP_PHYS_BIT_TOKEN_SIZE_6) { pr_err("gsp-phys-vbios: invalid BIT token size %u\n", @@ -685,7 +698,17 @@ int gsp_phys_vbios_parse_fwsec(const struct gsp_phys_vbios *img, &data_ptr)) continue; } else { - data_ptr = 0; + /* + * 6-byte tokens ("2b2w": TokenId, DataVersion, + * DataSize u16, DataPtr u16) carry a 16-bit + * DataPtr at offset 4 which zero-extends into + * the u32. A token whose DataPtr does not fit + * the image is skipped, matching a failed + * whole-token read in the reference. + */ + if (!gsp_phys_img_read(img, token_offset + 4, 2, + &data_ptr)) + continue; } if (token_id == GSP_PHYS_BIT_TOKEN_BIOSDATA && |
