Alexandre Courbot
2015-Oct-26 05:47 UTC
[Nouveau] [PATCH 2/3] 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 at nvidia.com>
---
drm/nouveau/nvkm/engine/gr/gf100.c | 56 +++++++++++++++++++++++++++++++-------
1 file changed, 46 insertions(+), 10 deletions(-)
diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c
b/drm/nouveau/nvkm/engine/gr/gf100.c
index dda7a7d224c9..67691941d7ba 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;
--
2.6.1
Alexandre Courbot
2015-Oct-26 05:47 UTC
[Nouveau] [PATCH 3/3] gm20b: secure-boot FECS falcon
Enable secure boot of FECS for GM20B.
Signed-off-by: Alexandre Courbot <acourbot at nvidia.com>
---
drm/nouveau/nvkm/engine/device/base.c | 4 ++++
drm/nouveau/nvkm/engine/gr/gm20b.c | 6 ++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drm/nouveau/nvkm/engine/device/base.c
b/drm/nouveau/nvkm/engine/device/base.c
index 3e26fc5431d7..94ffc005c2cc 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -2043,6 +2043,10 @@ nv12b_chipset = {
.fifo = gm20b_fifo_new,
.gr = gm20b_gr_new,
.sw = gf100_sw_new,
+ .secure_boot = {
+ .managed_falcons = BIT(LSF_FALCON_ID_FECS),
+ .boot_falcon = LSF_FALCON_ID_PMU,
+ },
};
static int
diff --git a/drm/nouveau/nvkm/engine/gr/gm20b.c
b/drm/nouveau/nvkm/engine/gr/gm20b.c
index 65b6e3d1e90d..eabac5d1e44b 100644
--- a/drm/nouveau/nvkm/engine/gr/gm20b.c
+++ b/drm/nouveau/nvkm/engine/gr/gm20b.c
@@ -32,12 +32,10 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
struct nvkm_device *device = gr->base.engine.subdev.device;
u32 val;
- /* TODO this needs to be removed once secure boot works */
- if (1) {
+ /* Bypass MMU check for non-secure boot */
+ if (!device->chip->secure_boot.managed_falcons)
nvkm_wr32(device, 0x100ce4, 0xffffffff);
- }
- /* TODO update once secure boot works */
val = nvkm_rd32(device, 0x100c80);
val &= 0xf000087f;
nvkm_wr32(device, 0x418880, val);
--
2.6.1