summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2015-10-25 13:23:57 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2015-12-11 17:42:26 +0900
commit41359c9abe14e565f04b5770c00a93ba88930bdc (patch)
tree1c2c605145b64f026de221cdd962487372b33846
parentf74c9d1c9e4f996367579a83a4bcd5b87bdb3d7b (diff)
downloadnouveau-41359c9abe14e565f04b5770c00a93ba88930bdc.tar.gz
gr: support for securely-booted FECS firmware
Trigger the loading of FECS/GPCCS using secure boot if required, and start managed falcons using the CPUCTL_ALIAS register since CPUCTL is protected in that case. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r--drm/nouveau/nvkm/engine/gr/gf100.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c
index 3c6effbf1..61b705111 100644
--- a/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -27,6 +27,7 @@
#include <core/client.h>
#include <core/option.h>
+#include <core/secure_boot.h>
#include <subdev/fb.h>
#include <subdev/mc.h>
#include <subdev/pmu.h>
@@ -1344,16 +1345,40 @@ gf100_gr_init_ctxctl(struct gf100_gr *gr)
if (gr->firmware) {
/* load fuc microcode */
nvkm_mc_unk260(device->mc, 0);
- gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c, &gr->fuc409d);
- gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac, &gr->fuc41ad);
+
+ if (nvkm_is_secure(device, LSF_FALCON_ID_FECS) ||
+ nvkm_is_secure(device, LSF_FALCON_ID_GPCCS)) {
+ int err = nvkm_secure_boot(subdev->device);
+
+ if (err)
+ return err;
+ }
+
+ if (!nvkm_is_secure(device, LSF_FALCON_ID_FECS))
+ gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c,
+ &gr->fuc409d);
+
+ if (!nvkm_is_secure(device, LSF_FALCON_ID_GPCCS))
+ gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac,
+ &gr->fuc41ad);
+
nvkm_mc_unk260(device->mc, 1);
/* start both of them running */
nvkm_wr32(device, 0x409840, 0xffffffff);
nvkm_wr32(device, 0x41a10c, 0x00000000);
nvkm_wr32(device, 0x40910c, 0x00000000);
- nvkm_wr32(device, 0x41a100, 0x00000002);
- nvkm_wr32(device, 0x409100, 0x00000002);
+ /* Use FALCON_CPUCTL_ALIAS if falcon is in secure mode */
+ if (nvkm_rd32(device, 0x41a100) & 0x40)
+ nvkm_wr32(device, 0x41a130, 0x00000002);
+ else
+ nvkm_wr32(device, 0x41a100, 0x00000002);
+
+ /* Use FALCON_CPUCTL_ALIAS if falcon is in secure mode */
+ if (nvkm_rd32(device, 0x409100) & 0x40)
+ nvkm_wr32(device, 0x409130, 0x00000002);
+ else
+ nvkm_wr32(device, 0x409100, 0x00000002);
if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, 0x409800) & 0x00000001)
break;
@@ -1663,6 +1688,7 @@ int
gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
int index, struct gf100_gr *gr)
{
+ struct nvkm_subdev *subdev = &gr->base.engine.subdev;
int ret;
gr->func = func;
@@ -1676,12 +1702,22 @@ gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
return ret;
if (gr->firmware) {
- nvkm_info(&gr->base.engine.subdev, "using external firmware\n");
- if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
- gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
- gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
- gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
- return -ENODEV;
+ nvkm_info(subdev, "using external firmware\n");
+ if (!nvkm_is_secure(device, LSF_FALCON_ID_FECS)) {
+ if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
+ gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d))
+ return -ENODEV;
+ } else {
+ nvkm_info(subdev, "FECS firmware securely managed\n");
+ }
+
+ if (!nvkm_is_secure(device, LSF_FALCON_ID_GPCCS)) {
+ if (gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
+ gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
+ return -ENODEV;
+ } else {
+ nvkm_info(subdev, "GPCCS firmware securely managed\n");
+ }
}
return 0;