From 36fbd3bf40fef0557ab0901fff091db72b82cf2a Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Fri, 16 Aug 2019 10:32:20 -0400 Subject: [PATCH] gpu: nvgpu: check Board ID and VBIOS version Check that current VBIOS meets minimal version requirement. Read VBIOS Board ID to identify the board SKU. Warn if VBIOS version is lower than expected version for this SKU. Warn if Board ID is unknown. Bug 200544064 Change-Id: I83176ab1342c9b8c8f5d273dd5ac00e6e26a0e7d Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/2176974 (cherry picked from commit 621a10c123b9ba25e3cb89dee340741c4ad2cd8e) Reviewed-on: https://git-master.nvidia.com/r/2176931 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/vbios/bios.c | 12 +++ .../gpu/nvgpu/common/vbios/bios_sw_gv100.c | 21 ++---- .../gpu/nvgpu/common/vbios/bios_sw_tu104.c | 75 +++++++++++++++++++ drivers/gpu/nvgpu/include/nvgpu/bios.h | 8 ++ drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 4 - drivers/gpu/nvgpu/os/linux/driver_common.c | 2 - drivers/gpu/nvgpu/os/linux/pci.c | 3 - drivers/gpu/nvgpu/os/linux/platform_gk20a.h | 10 --- 8 files changed, 101 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/nvgpu/common/vbios/bios.c b/drivers/gpu/nvgpu/common/vbios/bios.c index ca4ad4257..a1fa1df05 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios.c +++ b/drivers/gpu/nvgpu/common/vbios/bios.c @@ -405,6 +405,14 @@ static void nvgpu_bios_parse_memory_ptrs(struct gk20a *g, u16 offset, u8 version return; } +static void nvgpu_bios_parse_bios_board_id_ptrs(struct gk20a *g, u16 offset) +{ + struct bios_board_id board; + + nvgpu_memcpy((u8 *)&board, &g->bios->data[offset], sizeof(board)); + g->bios->vbios_board_id = board.board_id; +} + static void nvgpu_bios_parse_devinit_appinfo(struct gk20a *g, u32 dmem_offset) { struct devinit_engine_interface interface; @@ -756,6 +764,10 @@ static void nvgpu_bios_parse_bit(struct gk20a *g, u32 offset) nvgpu_bios_parse_memory_ptrs(g, token.data_ptr, token.data_version); break; + case TOKEN_ID_BIOS_BOARD_ID_PTRS: + nvgpu_bios_parse_bios_board_id_ptrs(g, + token.data_ptr); + break; default: nvgpu_log_info(g, "Token id %d not supported", token.token_id); diff --git a/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c b/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c index 93c502e83..ad6371f09 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c +++ b/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c @@ -255,21 +255,11 @@ int gv100_bios_init(struct gk20a *g) goto free_firmware; } - if (g->bios->vbios_version < g->vbios_min_version) { - nvgpu_err(g, "unsupported VBIOS version %08x", - g->bios->vbios_version); - err = -EINVAL; - goto free_firmware; - } else { - nvgpu_info(g, "VBIOS version %08x", g->bios->vbios_version); - } - - if ((g->vbios_compatible_version != 0U) && - (g->bios->vbios_version != g->vbios_compatible_version)) { - nvgpu_err(g, "VBIOS version %08x is not officially supported.", - g->bios->vbios_version); - nvgpu_err(g, "Update to VBIOS %08x, or use at your own risks.", - g->vbios_compatible_version); + if (g->bios->verify_version != NULL) { + if (g->bios->verify_version(g) < 0) { + err = -EINVAL; + goto free_firmware; + } } nvgpu_log_fn(g, "done"); @@ -384,6 +374,7 @@ void nvgpu_gv100_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios) { bios->init = gv100_bios_init; + bios->verify_version = NULL; bios->preos_wait_for_halt = gv100_bios_preos_wait_for_halt; bios->preos_reload_check = gv100_bios_preos_reload_check; bios->preos_bios = gv100_bios_preos; diff --git a/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c b/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c index 278a5e00c..042584eac 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c +++ b/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c @@ -36,6 +36,80 @@ #define NV_PGC6_AON_SECURE_SCRATCH_GROUP_05_0_GFW_BOOT_PROGRESS_COMPLETED \ 0xFFU +#define NVGPU_PG189_MIN_VBIOS 0x90041800U + +#define NVGPU_PG189_0600_VBIOS 0x90047200U +#define NVGPU_PG189_0601_VBIOS 0x90045a00U +#define NVGPU_PG189_0610_VBIOS 0U + +struct nvgpu_vbios_board { + u16 board_id; + u32 vbios_version; +}; + +#define NVGPU_PG189_NUM_VBIOS_BOARDS 4U + +static struct nvgpu_vbios_board vbios_boards[NVGPU_PG189_NUM_VBIOS_BOARDS] = { + /* SKU 600 ES/CS, SKU 606*/ + [0] = { + .board_id = 0x0068, + .vbios_version = NVGPU_PG189_0600_VBIOS, + }, + /* SKU 600 QS */ + [1] = { + .board_id = 0x0183, + .vbios_version = NVGPU_PG189_0600_VBIOS, + }, + /* SKU 601 CS */ + [2] = { + .board_id = 0x00E8, + .vbios_version = NVGPU_PG189_0601_VBIOS, + }, + /* SKU 610 */ + [3] = { + .board_id = 0x01a3, + .vbios_version = NVGPU_PG189_0610_VBIOS, + }, +}; + +static int tu104_bios_verify_version(struct gk20a *g) +{ + struct nvgpu_vbios_board *board = NULL; + u32 i; + + nvgpu_info(g, "VBIOS board id %04x", g->bios->vbios_board_id); + + nvgpu_info(g, "VBIOS version %08x:%02x\n", + g->bios->vbios_version, + g->bios->vbios_oem_version); + + if (g->bios->vbios_version < NVGPU_PG189_MIN_VBIOS) { + nvgpu_err(g, "unsupported VBIOS version %08x", + g->bios->vbios_version); + return -EINVAL; + } + + for (i = 0; i < NVGPU_PG189_NUM_VBIOS_BOARDS; i++) { + if (g->bios->vbios_board_id == vbios_boards[i].board_id) { + board = &vbios_boards[i]; + } + } + + if (board == NULL) { + nvgpu_warn(g, "unknown board id %04x", + g->bios->vbios_board_id); + return 0; + } + + if ((board->vbios_version != 0U) && + (g->bios->vbios_version < board->vbios_version)) { + nvgpu_warn(g, "VBIOS version should be at least %08x", + board->vbios_version); + } + + return 0; +} + int tu104_bios_verify_devinit(struct gk20a *g) { struct nvgpu_timeout timeout; @@ -80,6 +154,7 @@ void nvgpu_tu104_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios) { bios->init = tu104_bios_init; + bios->verify_version = tu104_bios_verify_version; bios->preos_wait_for_halt = NULL; bios->preos_reload_check = NULL; bios->preos_bios = NULL; diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h index eb2f78bca..dc44452e4 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/bios.h +++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h @@ -1239,6 +1239,7 @@ struct bios_bit { #define TOKEN_ID_CLOCK_PTRS 0x43U #define TOKEN_ID_VIRT_PTRS 0x56U #define TOKEN_ID_MEMORY_PTRS 0x4DU +#define TOKEN_ID_BIOS_BOARD_ID_PTRS 0x69U #define MEMORY_PTRS_V1 1U #define MEMORY_PTRS_V2 2U @@ -1432,6 +1433,11 @@ struct pci_ext_data_struct { u8 flags; } __packed; +struct bios_board_id { + u8 padding[11]; + u16 board_id; +} __packed; + struct nvgpu_bios_ucode { u8 *bootloader; u32 bootloader_phys_base; @@ -1448,6 +1454,7 @@ struct nvgpu_bios_ucode { struct nvgpu_bios { u32 vbios_version; u8 vbios_oem_version; + u16 vbios_board_id; u8 *data; size_t size; @@ -1476,6 +1483,7 @@ struct nvgpu_bios { u32 nvlink_config_data_offset; int (*init)(struct gk20a *g); + int (*verify_version)(struct gk20a *g); int (*preos_wait_for_halt)(struct gk20a *g); void (*preos_reload_check)(struct gk20a *g); int (*preos_bios)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 1c8ba8e18..e9e2f5a5f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -2210,10 +2210,6 @@ struct gk20a { struct nvgpu_mem_alloc_tracker *kmallocs; #endif - /* The minimum VBIOS version supported */ - u32 vbios_min_version; - u32 vbios_compatible_version; - /* memory training sequence and mclk switch scripts */ u32 mem_config_idx; diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index fb4643a13..8cdf57e16 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -211,8 +211,6 @@ static void nvgpu_init_vbios_vars(struct gk20a *g) struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); nvgpu_set_enabled(g, NVGPU_PMU_RUN_PREOS, platform->run_preos); - g->vbios_min_version = platform->vbios_min_version; - g->vbios_compatible_version = platform->vbios_compatible_version; } static void nvgpu_init_ltc_vars(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index 68e5c0e27..21c3bc0f8 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -108,7 +108,6 @@ static struct gk20a_platform nvgpu_pci_device[] = { .unify_address_spaces = true, .honors_aperture = true, .dma_mask = DMA_BIT_MASK(40), - .vbios_min_version = 0x1, .hardcode_sw_threshold = false, .unified_memory = false, }, @@ -147,8 +146,6 @@ static struct gk20a_platform nvgpu_pci_device[] = { .unify_address_spaces = true, .honors_aperture = true, .dma_mask = DMA_BIT_MASK(40), - .vbios_min_version = 0x90041800, - .vbios_compatible_version = 0x90045A00, .hardcode_sw_threshold = false, .has_syncpoints = true, }, diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h index 5d041d0a4..6270fbc05 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h @@ -277,16 +277,6 @@ struct gk20a_platform { */ u64 dma_mask; - /* minimum supported VBIOS version. - * nvgpu driver is not loaded if VBIOS < min VBIOS version - */ - u32 vbios_min_version; - - /* blessed VBIOS version - * if defined, a warning is given if VBIOS differs. - */ - u32 vbios_compatible_version; - /* true if we run preos microcode on this board */ bool run_preos;