diff --git a/drivers/gpu/nvgpu/os/posix/firmware.c b/drivers/gpu/nvgpu/os/posix/firmware.c index b648da269..3e97038d3 100644 --- a/drivers/gpu/nvgpu/os/posix/firmware.c +++ b/drivers/gpu/nvgpu/os/posix/firmware.c @@ -20,16 +20,135 @@ * DEALINGS IN THE SOFTWARE. */ +#include +#include +#include + +#include +#include #include +#include + +#define FW_MAX_PATH_SIZE 2048U +#define NVGPU_UNITTEST_UCODE_PATH "/firmware/" + +static int nvgpu_ucode_load(struct gk20a *g, const char *path, + struct nvgpu_firmware *ucode) +{ + struct stat buf; + size_t bufsize; + ssize_t len; + int fd = -1; + int ret = -1; + u8 *data, *data1; + + fd = open(path, O_RDONLY); + if (fd < 0) { + nvgpu_err(g, "fw: %s open failed", path); + goto done; + } + + if (fstat(fd, &buf) == -1) { + nvgpu_err(g, "fw: fstat failed"); + goto done; + } + + if (buf.st_size <= 0) { + nvgpu_err(g, "fw: invalid buf.st_size"); + goto done; + } + bufsize = (size_t)buf.st_size; + + data = (u8 *)nvgpu_kmalloc(g, bufsize); + if (data == NULL) { + nvgpu_err(g, "fw: malloc failed"); + goto done; + } + data1 = data; + + while (bufsize > 0UL) { + len = read(fd, data, bufsize); + if (len < 0) { + ret = errno; + nvgpu_err(g, "fw: read failed"); + goto err; + } + + if (len == 0) { + nvgpu_err(g, "fw load failed: read size mismatch"); + ret = -1; + goto err; + } + + data += len; + bufsize -= (size_t)len; + } + + ucode->data = data1; + ucode->size = (size_t)buf.st_size; + ret = 0; + goto done; + +err: + nvgpu_kfree(g, data); + +done: + if (fd >= 0) { + if (close(fd) != 0) { + nvgpu_err(g, "close() failed"); + } + } + + return ret; +} struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g, const char *fw_name, u32 flags) { + struct nvgpu_firmware *fw; + char full_path[FW_MAX_PATH_SIZE] = ""; + int ret; + size_t full_path_len; + + if (fw_name == NULL) { + return NULL; + } + + getcwd(full_path, FW_MAX_PATH_SIZE); + full_path_len = strlen(full_path); + full_path_len += strlen(fw_name); + full_path_len += strlen(NVGPU_UNITTEST_UCODE_PATH); + if (full_path_len >= FW_MAX_PATH_SIZE) { + nvgpu_err(g, "Invalid MAX_PATH_SIZE %lu %u", full_path_len, + FW_MAX_PATH_SIZE); + goto err; + } + + strcat(full_path, NVGPU_UNITTEST_UCODE_PATH); + strcat(full_path, fw_name); + + fw = nvgpu_kzalloc(g, sizeof(*fw)); + if (fw == NULL) { + nvgpu_err(g, "malloc failed"); + goto err; + } + + ret = nvgpu_ucode_load(g, full_path, fw); + if (ret != 0) { + nvgpu_err(g, "failed to load %s ucode", fw_name); + goto err_fw; + } + return fw; + +err_fw: + nvgpu_kfree(g, fw); +err: return NULL; } void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw) { - /* Noop. */ + nvgpu_kfree(g, fw->data); + nvgpu_kfree(g, fw); } diff --git a/userspace/Makefile.tmk b/userspace/Makefile.tmk index 3977cf22a..7945ebacc 100644 --- a/userspace/Makefile.tmk +++ b/userspace/Makefile.tmk @@ -62,15 +62,24 @@ NV_UNIT_SH=unit.sh NV_SUBMIT_UNIT_SH=nvgpu_submit_unit.sh NV_TESTLIST_PY=testlist.py NV_REQ_TESTS_JSON=required_tests.json +NV_NETD_IMG=NETD_img.bin +NV_FECS_IMG=fecs.bin +NV_GPCCS_IMG=gpccs.bin NV_COMPONENT_SYSTEMIMAGE_DIR := $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/nvgpu_unit +NV_UNIT_REQ_FIRMWARE_DIR := $(NV_COMPONENT_SYSTEMIMAGE_DIR)/firmware systemimage:: $(NV_COMPONENT_SYSTEMIMAGE_DIR) $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_UNIT_SH) \ $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/$(NV_SUBMIT_UNIT_SH) \ $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_TESTLIST_PY) \ - $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_REQ_TESTS_JSON) + $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_REQ_TESTS_JSON) \ + $(NV_UNIT_REQ_FIRMWARE_DIR) $(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_NETD_IMG) \ + $(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_FECS_IMG) \ + $(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_GPCCS_IMG) #make the output directory $(NV_COMPONENT_SYSTEMIMAGE_DIR) : $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR) $(MKDIR_P) $@ +$(NV_UNIT_REQ_FIRMWARE_DIR) : $(NV_COMPONENT_SYSTEMIMAGE_DIR) + $(MKDIR_P) $@ #copy the test script $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_UNIT_SH) : $(NV_COMPONENT_DIR)/$(NV_UNIT_SH) $(NV_COMPONENT_SYSTEMIMAGE_DIR) @@ -82,7 +91,12 @@ $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_TESTLIST_PY) : $(NV_COMPONENT_DIR)/$(NV_TES $(CP) $< $@ $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_REQ_TESTS_JSON) : $(NV_COMPONENT_DIR)/$(NV_REQ_TESTS_JSON) $(NV_COMPONENT_SYSTEMIMAGE_DIR) $(CP) $< $@ - +$(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_NETD_IMG) : $(NV_COMPONENT_DIR)/firmware/$(NV_NETD_IMG) $(NV_UNIT_REQ_FIRMWARE_DIR) + $(CP) $< $@ +$(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_FECS_IMG) : $(NV_COMPONENT_DIR)/firmware/$(NV_FECS_IMG) $(NV_UNIT_REQ_FIRMWARE_DIR) + $(CP) $< $@ +$(NV_UNIT_REQ_FIRMWARE_DIR)/$(NV_GPCCS_IMG) : $(NV_COMPONENT_DIR)/firmware/$(NV_GPCCS_IMG) $(NV_UNIT_REQ_FIRMWARE_DIR) + $(CP) $< $@ include $(NV_BUILD_NVTEST_EXECUTABLE) diff --git a/userspace/firmware/NETD_img.bin b/userspace/firmware/NETD_img.bin new file mode 100644 index 000000000..f80194cab Binary files /dev/null and b/userspace/firmware/NETD_img.bin differ diff --git a/userspace/firmware/fecs.bin b/userspace/firmware/fecs.bin new file mode 100644 index 000000000..2e3e996bb Binary files /dev/null and b/userspace/firmware/fecs.bin differ diff --git a/userspace/firmware/gpccs.bin b/userspace/firmware/gpccs.bin new file mode 100644 index 000000000..2e3e996bb Binary files /dev/null and b/userspace/firmware/gpccs.bin differ