summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2017-02-16 18:57:03 +0900
committerBen Skeggs <bskeggs@redhat.com>2017-03-07 17:04:07 +1000
commit73ec867086956cb09faf5613ea6a75f30b71a432 (patch)
treee142f49bdd6d440a9c74b944967dc7bde08e0f79
parent55b3305e0a7af14f537e819bdd9928b441605e4f (diff)
downloadnouveau-73ec867086956cb09faf5613ea6a75f30b71a432.tar.gz
secboot: put HS code loading code into own file
We will also need to load HS blobs outside of acr_r352 (for instance, to run the NVDEC VPR scrubber), so make this code reusable. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/Kbuild1
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/acr_r352.c100
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/acr_r352.h27
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/hs_ucode.c97
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/hs_ucode.h81
5 files changed, 182 insertions, 124 deletions
diff --git a/drm/nouveau/nvkm/subdev/secboot/Kbuild b/drm/nouveau/nvkm/subdev/secboot/Kbuild
index 62ee784a4..566c8593a 100644
--- a/drm/nouveau/nvkm/subdev/secboot/Kbuild
+++ b/drm/nouveau/nvkm/subdev/secboot/Kbuild
@@ -1,4 +1,5 @@
nvkm-y += nvkm/subdev/secboot/base.o
+nvkm-y += nvkm/subdev/secboot/hs_ucode.o
nvkm-y += nvkm/subdev/secboot/ls_ucode_gr.o
nvkm-y += nvkm/subdev/secboot/ls_ucode_msgqueue.o
nvkm-y += nvkm/subdev/secboot/acr.o
diff --git a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
index 72ca537b0..993a38eb3 100644
--- a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
+++ b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
@@ -21,6 +21,7 @@
*/
#include "acr_r352.h"
+#include "hs_ucode.h"
#include <core/gpuobj.h>
#include <core/firmware.h>
@@ -32,31 +33,6 @@
#include <engine/sec2.h>
/**
- * struct hsf_fw_header - HS firmware descriptor
- * @sig_dbg_offset: offset of the debug signature
- * @sig_dbg_size: size of the debug signature
- * @sig_prod_offset: offset of the production signature
- * @sig_prod_size: size of the production signature
- * @patch_loc: offset of the offset (sic) of where the signature is
- * @patch_sig: offset of the offset (sic) to add to sig_*_offset
- * @hdr_offset: offset of the load header (see struct hs_load_header)
- * @hdr_size: size of above header
- *
- * This structure is embedded in the HS firmware image at
- * hs_bin_hdr.header_offset.
- */
-struct hsf_fw_header {
- u32 sig_dbg_offset;
- u32 sig_dbg_size;
- u32 sig_prod_offset;
- u32 sig_prod_size;
- u32 patch_loc;
- u32 patch_sig;
- u32 hdr_offset;
- u32 hdr_size;
-};
-
-/**
* struct acr_r352_flcn_bl_desc - DMEM bootloader descriptor
* @signature: 16B signature for secure code. 0s if no secure code
* @ctx_dma: DMA context to be used by BL while loading code/data
@@ -599,47 +575,6 @@ cleanup:
-/**
- * acr_r352_hsf_patch_signature() - patch HS blob with correct signature for
- * specified falcon.
- */
-static void
-acr_r352_hsf_patch_signature(const struct nvkm_falcon *falcon, void *acr_image,
- bool new_format)
-{
- struct fw_bin_header *hsbin_hdr = acr_image;
- struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset;
- void *hs_data = acr_image + hsbin_hdr->data_offset;
- void *sig;
- u32 sig_size;
- u32 patch_loc, patch_sig;
-
- /*
- * I had the brilliant idea to "improve" the binary format by
- * removing this useless indirection. However to make NVIDIA files
- * directly compatible, let's support both format.
- */
- if (new_format) {
- patch_loc = fw_hdr->patch_loc;
- patch_sig = fw_hdr->patch_sig;
- } else {
- patch_loc = *(u32 *)(acr_image + fw_hdr->patch_loc);
- patch_sig = *(u32 *)(acr_image + fw_hdr->patch_sig);
- }
-
- /* Falcon in debug or production mode? */
- if (falcon->debug) {
- sig = acr_image + fw_hdr->sig_dbg_offset;
- sig_size = fw_hdr->sig_dbg_size;
- } else {
- sig = acr_image + fw_hdr->sig_prod_offset;
- sig_size = fw_hdr->sig_prod_size;
- }
-
- /* Patch signature */
- memcpy(hs_data + patch_loc, sig + patch_sig, sig_size);
-}
-
void
acr_r352_fixup_hs_desc(struct acr_r352 *acr, struct nvkm_secboot *sb,
void *_desc)
@@ -687,37 +622,6 @@ acr_r352_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
bl_desc->data_size = hdr->data_size;
}
-void *
-acr_r352_load_hs_blob(struct nvkm_secboot *sb, const struct nvkm_falcon *falcon,
- const char *fw)
-{
- struct nvkm_subdev *subdev = &sb->subdev;
- void *acr_image;
- bool new_format;
-
- acr_image = nvkm_acr_load_firmware(subdev, fw, 0);
- if (IS_ERR(acr_image))
- return acr_image;
-
- /* detect the format to define how signature should be patched */
- switch (((u32 *)acr_image)[0]) {
- case 0x3b1d14f0:
- new_format = true;
- break;
- case 0x000010de:
- new_format = false;
- break;
- default:
- nvkm_error(subdev, "unknown header for HS blob %s\n", fw);
- return ERR_PTR(-EINVAL);
- }
-
- /* Patch signature */
- acr_r352_hsf_patch_signature(falcon, acr_image, new_format);
-
- return acr_image;
-}
-
/**
* acr_r352_prepare_hs_blob - load and prepare a HS blob and BL descriptor
*
@@ -740,7 +644,7 @@ acr_r352_prepare_hs_blob(struct acr_r352 *acr, struct nvkm_secboot *sb,
void *acr_data;
int ret;
- acr_image = acr_r352_load_hs_blob(sb, sb->boot_falcon, fw);
+ acr_image = hs_ucode_load_blob(subdev, sb->boot_falcon, fw);
if (IS_ERR(acr_image))
return PTR_ERR(acr_image);
diff --git a/drm/nouveau/nvkm/subdev/secboot/acr_r352.h b/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
index b610152ea..6e8852056 100644
--- a/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
+++ b/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
@@ -24,6 +24,7 @@
#include "acr.h"
#include "ls_ucode.h"
+#include "hs_ucode.h"
struct ls_ucode_img;
@@ -33,32 +34,6 @@ struct ls_ucode_img;
#define LSF_FLAG_DMACTL_REQ_CTX 4
#define LSF_FLAG_FORCE_PRIV_LOAD 8
-/*
- * HS blob structures
- */
-
-/**
- * struct hsf_load_header - HS firmware load header
- */
-struct hsf_load_header {
- u32 non_sec_code_off;
- u32 non_sec_code_size;
- u32 data_dma_base;
- u32 data_size;
- u32 num_apps;
- /*
- * Organized as follows:
- * - app0_code_off
- * - app1_code_off
- * - ...
- * - appn_code_off
- * - app0_code_size
- * - app1_code_size
- * - ...
- */
- u32 apps[0];
-};
-
static inline u32
hsf_load_header_app_off(const struct hsf_load_header *hdr, u32 app)
{
diff --git a/drm/nouveau/nvkm/subdev/secboot/hs_ucode.c b/drm/nouveau/nvkm/subdev/secboot/hs_ucode.c
new file mode 100644
index 000000000..6b33182dd
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/secboot/hs_ucode.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "hs_ucode.h"
+#include "ls_ucode.h"
+#include "acr.h"
+
+#include <engine/falcon.h>
+
+/**
+ * hs_ucode_patch_signature() - patch HS blob with correct signature for
+ * specified falcon.
+ */
+static void
+hs_ucode_patch_signature(const struct nvkm_falcon *falcon, void *acr_image,
+ bool new_format)
+{
+ struct fw_bin_header *hsbin_hdr = acr_image;
+ struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset;
+ void *hs_data = acr_image + hsbin_hdr->data_offset;
+ void *sig;
+ u32 sig_size;
+ u32 patch_loc, patch_sig;
+
+ /*
+ * I had the brilliant idea to "improve" the binary format by
+ * removing this useless indirection. However to make NVIDIA files
+ * directly compatible, let's support both format.
+ */
+ if (new_format) {
+ patch_loc = fw_hdr->patch_loc;
+ patch_sig = fw_hdr->patch_sig;
+ } else {
+ patch_loc = *(u32 *)(acr_image + fw_hdr->patch_loc);
+ patch_sig = *(u32 *)(acr_image + fw_hdr->patch_sig);
+ }
+
+ /* Falcon in debug or production mode? */
+ if (falcon->debug) {
+ sig = acr_image + fw_hdr->sig_dbg_offset;
+ sig_size = fw_hdr->sig_dbg_size;
+ } else {
+ sig = acr_image + fw_hdr->sig_prod_offset;
+ sig_size = fw_hdr->sig_prod_size;
+ }
+
+ /* Patch signature */
+ memcpy(hs_data + patch_loc, sig + patch_sig, sig_size);
+}
+
+void *
+hs_ucode_load_blob(struct nvkm_subdev *subdev, const struct nvkm_falcon *falcon,
+ const char *fw)
+{
+ void *acr_image;
+ bool new_format;
+
+ acr_image = nvkm_acr_load_firmware(subdev, fw, 0);
+ if (IS_ERR(acr_image))
+ return acr_image;
+
+ /* detect the format to define how signature should be patched */
+ switch (((u32 *)acr_image)[0]) {
+ case 0x3b1d14f0:
+ new_format = true;
+ break;
+ case 0x000010de:
+ new_format = false;
+ break;
+ default:
+ nvkm_error(subdev, "unknown header for HS blob %s\n", fw);
+ return ERR_PTR(-EINVAL);
+ }
+
+ hs_ucode_patch_signature(falcon, acr_image, new_format);
+
+ return acr_image;
+}
diff --git a/drm/nouveau/nvkm/subdev/secboot/hs_ucode.h b/drm/nouveau/nvkm/subdev/secboot/hs_ucode.h
new file mode 100644
index 000000000..d8cfc6f77
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/secboot/hs_ucode.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NVKM_SECBOOT_HS_UCODE_H__
+#define __NVKM_SECBOOT_HS_UCODE_H__
+
+#include <core/os.h>
+#include <core/subdev.h>
+
+struct nvkm_falcon;
+
+/**
+ * struct hsf_fw_header - HS firmware descriptor
+ * @sig_dbg_offset: offset of the debug signature
+ * @sig_dbg_size: size of the debug signature
+ * @sig_prod_offset: offset of the production signature
+ * @sig_prod_size: size of the production signature
+ * @patch_loc: offset of the offset (sic) of where the signature is
+ * @patch_sig: offset of the offset (sic) to add to sig_*_offset
+ * @hdr_offset: offset of the load header (see struct hs_load_header)
+ * @hdr_size: size of above header
+ *
+ * This structure is embedded in the HS firmware image at
+ * hs_bin_hdr.header_offset.
+ */
+struct hsf_fw_header {
+ u32 sig_dbg_offset;
+ u32 sig_dbg_size;
+ u32 sig_prod_offset;
+ u32 sig_prod_size;
+ u32 patch_loc;
+ u32 patch_sig;
+ u32 hdr_offset;
+ u32 hdr_size;
+};
+
+/**
+ * struct hsf_load_header - HS firmware load header
+ */
+struct hsf_load_header {
+ u32 non_sec_code_off;
+ u32 non_sec_code_size;
+ u32 data_dma_base;
+ u32 data_size;
+ u32 num_apps;
+ /*
+ * Organized as follows:
+ * - app0_code_off
+ * - app1_code_off
+ * - ...
+ * - appn_code_off
+ * - app0_code_size
+ * - app1_code_size
+ * - ...
+ */
+ u32 apps[0];
+};
+
+void *hs_ucode_load_blob(struct nvkm_subdev *, const struct nvkm_falcon *,
+ const char *);
+
+#endif