diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2015-10-25 13:23:57 +0900 |
---|---|---|
committer | Alexandre Courbot <acourbot@nvidia.com> | 2015-11-11 18:52:45 +0900 |
commit | a720ffa2c3bb468becfeb76ee9d6f7f987d75ad4 (patch) | |
tree | 4d3b89eab0a27b6a7c8f13208efd9f58cbaeb160 /drm/nouveau/nvkm/engine | |
parent | 010ec2f3c32ea164d862e19377cfb3f22a20248d (diff) | |
download | nouveau-a720ffa2c3bb468becfeb76ee9d6f7f987d75ad4.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>
Diffstat (limited to 'drm/nouveau/nvkm/engine')
-rw-r--r-- | drm/nouveau/nvkm/engine/gr/gf100.c | 56 |
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 dda7a7d22..67691941d 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> @@ -1342,16 +1343,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; @@ -1659,6 +1684,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; @@ -1672,12 +1698,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; |