summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2015-12-18 17:24:48 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2015-12-18 17:28:42 +0900
commit9bbfb71f9c93a7e2fef68dbed040d859de2a85f6 (patch)
tree9eebd08217a719fe550a3f84245f9f57f684c4dc
parentc77a645cb43dbbb201ac7cc3392ca7bad2b39c58 (diff)
downloadnouveau-9bbfb71f9c93a7e2fef68dbed040d859de2a85f6.tar.gz
sb: move to subdev
-rw-r--r--drm/nouveau/include/nvkm/core/device.h10
-rw-r--r--drm/nouveau/include/nvkm/subdev/secboot.h (renamed from drm/nouveau/include/nvkm/core/secure_boot.h)47
-rw-r--r--drm/nouveau/nvkm/core/Kbuild1
-rw-r--r--drm/nouveau/nvkm/core/subdev.c1
-rw-r--r--drm/nouveau/nvkm/engine/device/base.c24
-rw-r--r--drm/nouveau/nvkm/engine/device/priv.h1
-rw-r--r--drm/nouveau/nvkm/engine/gr/gf100.c2
-rw-r--r--drm/nouveau/nvkm/engine/gr/gm20b.c2
-rw-r--r--drm/nouveau/nvkm/subdev/Kbuild1
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/Kbuild1
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/base.c (renamed from drm/nouveau/nvkm/core/secure_boot.c)246
-rw-r--r--drm/nouveau/nvkm/subdev/secboot/priv.h39
12 files changed, 225 insertions, 150 deletions
diff --git a/drm/nouveau/include/nvkm/core/device.h b/drm/nouveau/include/nvkm/core/device.h
index 19e75bb0f..8a544a8f5 100644
--- a/drm/nouveau/include/nvkm/core/device.h
+++ b/drm/nouveau/include/nvkm/core/device.h
@@ -24,6 +24,7 @@ enum nvkm_devidx {
NVKM_SUBDEV_VOLT,
NVKM_SUBDEV_THERM,
NVKM_SUBDEV_CLK,
+ NVKM_SUBDEV_SECBOOT,
NVKM_ENGINE_DMAOBJ,
NVKM_ENGINE_IFB,
@@ -122,6 +123,7 @@ struct nvkm_device {
struct nvkm_therm *therm;
struct nvkm_timer *timer;
struct nvkm_volt *volt;
+ struct nvkm_secboot *secboot;
struct nvkm_engine *bsp;
struct nvkm_engine *ce[3];
@@ -188,6 +190,7 @@ struct nvkm_device_chip {
int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **);
int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **);
int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **);
+ int (*secboot)(struct nvkm_device *, int idx, struct nvkm_secboot **);
int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **);
@@ -208,13 +211,6 @@ struct nvkm_device_chip {
int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **);
int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **);
-
- struct {
- /* Bit-mask of IDs of managed falcons. 0 means no secure boot */
- unsigned long managed_falcons;
- /* ID of the falcon that will perform secure boot */
- unsigned long boot_falcon;
- } secure_boot;
};
struct nvkm_device *nvkm_device_find(u64 name);
diff --git a/drm/nouveau/include/nvkm/core/secure_boot.h b/drm/nouveau/include/nvkm/subdev/secboot.h
index ddec92bb8..5dc2f2c4d 100644
--- a/drm/nouveau/include/nvkm/core/secure_boot.h
+++ b/drm/nouveau/include/nvkm/subdev/secboot.h
@@ -32,21 +32,42 @@
#define LSF_FALCON_ID_END 4
#define LSF_FALCON_ID_INVALID 0xffffffff
-int nvkm_secure_boot_init(struct nvkm_device *);
-void nvkm_secure_boot_fini(struct nvkm_device *);
+/**
+ * @falcon_id: falcon that will perform secure boot
+ * @wpr_addr: physical address of the WPR region
+ * @wpr_size: size in bytes of the WPR region
+ * @ls_blob: LS blob of all the LS firmwares, signatures, bootloaders
+ * @ls_blob_size: size of the LS blob
+ * @ls_blob_nb_regions: number of LS firmwares that will be loaded
+*/
+struct nvkm_secboot {
+ const struct nvkm_secboot_func *func;
+ struct nvkm_subdev subdev;
+
+ u32 falcon_id;
+ u64 wpr_addr;
+ u32 wpr_size;
+
+ /* LS FWs, to be loaded by the HS ACR */
+ struct nvkm_gpuobj *ls_blob;
+ u32 ls_blob_size;
+ u16 ls_blob_nb_regions;
+
+ /* HS FW */
+ struct nvkm_gpuobj *acr_blob;
+ struct nvkm_vma acr_blob_vma;
+
+ /* HS bootloader */
+ void *hsbl_blob;
+
+};
+
+int gm200_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
+int gm20b_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
int nvkm_secure_boot(struct nvkm_device *);
-static inline bool
-nvkm_is_secure(struct nvkm_device *device, unsigned long falcon_id)
-{
- return device->chip->secure_boot.managed_falcons & BIT(falcon_id);
-}
-
-static inline bool
-nvkm_need_secure_boot(struct nvkm_device *device)
-{
- return device->chip->secure_boot.managed_falcons != 0;
-}
+bool
+nvkm_is_secure(struct nvkm_device *device, unsigned long falcon_id);
#endif
diff --git a/drm/nouveau/nvkm/core/Kbuild b/drm/nouveau/nvkm/core/Kbuild
index 9d2ecc0ef..7f66963f3 100644
--- a/drm/nouveau/nvkm/core/Kbuild
+++ b/drm/nouveau/nvkm/core/Kbuild
@@ -11,5 +11,4 @@ nvkm-y += nvkm/core/object.o
nvkm-y += nvkm/core/oproxy.o
nvkm-y += nvkm/core/option.o
nvkm-y += nvkm/core/ramht.o
-nvkm-y += nvkm/core/secure_boot.o
nvkm-y += nvkm/core/subdev.o
diff --git a/drm/nouveau/nvkm/core/subdev.c b/drm/nouveau/nvkm/core/subdev.c
index 7de98470a..d8b3d2a36 100644
--- a/drm/nouveau/nvkm/core/subdev.c
+++ b/drm/nouveau/nvkm/core/subdev.c
@@ -49,6 +49,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_THERM ] = "therm",
[NVKM_SUBDEV_TIMER ] = "tmr",
[NVKM_SUBDEV_VOLT ] = "volt",
+ [NVKM_SUBDEV_SECBOOT] = "secboot",
[NVKM_ENGINE_BSP ] = "bsp",
[NVKM_ENGINE_CE0 ] = "ce0",
[NVKM_ENGINE_CE1 ] = "ce1",
diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c
index a1debfc20..1d8e96f64 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -26,7 +26,6 @@
#include <core/notify.h>
#include <core/option.h>
-#include <core/secure_boot.h>
#include <subdev/bios.h>
@@ -1992,10 +1991,7 @@ nv124_chipset = {
.fifo = gm204_fifo_new,
.gr = gm204_gr_new,
.sw = gf100_sw_new,
- .secure_boot = {
- .managed_falcons = BIT(LSF_FALCON_ID_FECS) | BIT(LSF_FALCON_ID_GPCCS),
- .boot_falcon = LSF_FALCON_ID_PMU,
- },
+ .secboot = gm200_secboot_new,
};
static const struct nvkm_device_chip
@@ -2027,10 +2023,7 @@ nv126_chipset = {
.fifo = gm204_fifo_new,
.gr = gm206_gr_new,
.sw = gf100_sw_new,
- .secure_boot = {
- .managed_falcons = BIT(LSF_FALCON_ID_FECS) | BIT(LSF_FALCON_ID_GPCCS),
- .boot_falcon = LSF_FALCON_ID_PMU,
- },
+ .secboot = gm200_secboot_new,
};
static const struct nvkm_device_chip
@@ -2051,10 +2044,7 @@ 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,
- },
+ .secboot = gm20b_secboot_new,
};
static int
@@ -2105,6 +2095,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
_(THERM , device->therm , &device->therm->subdev);
_(TIMER , device->timer , &device->timer->subdev);
_(VOLT , device->volt , &device->volt->subdev);
+ _(SECBOOT, device->secboot, &device->secboot->subdev);
#undef _
default:
engine = nvkm_device_engine(device, index);
@@ -2265,9 +2256,6 @@ nvkm_device_init(struct nvkm_device *device)
ret = 0;
- if (nvkm_need_secure_boot(device))
- ret = nvkm_secure_boot_init(device);
-
time = ktime_to_us(ktime_get()) - time;
nvdev_trace(device, "init completed in %lldus\n", time);
return 0;
@@ -2292,9 +2280,6 @@ nvkm_device_del(struct nvkm_device **pdevice)
mutex_lock(&nv_devices_mutex);
device->disable_mask = 0;
- if (nvkm_need_secure_boot(device))
- nvkm_secure_boot_fini(device);
-
for (i = NVKM_SUBDEV_NR - 1; i >= 0; i--) {
struct nvkm_subdev *subdev =
nvkm_device_subdev(device, i);
@@ -2560,6 +2545,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
_(NVKM_SUBDEV_THERM , therm);
_(NVKM_SUBDEV_TIMER , timer);
_(NVKM_SUBDEV_VOLT , volt);
+ _(NVKM_SUBDEV_SECBOOT, secboot);
_(NVKM_ENGINE_BSP , bsp);
_(NVKM_ENGINE_CE0 , ce[0]);
_(NVKM_ENGINE_CE1 , ce[1]);
diff --git a/drm/nouveau/nvkm/engine/device/priv.h b/drm/nouveau/nvkm/engine/device/priv.h
index ed3ad2c30..03fe0afbf 100644
--- a/drm/nouveau/nvkm/engine/device/priv.h
+++ b/drm/nouveau/nvkm/engine/device/priv.h
@@ -22,6 +22,7 @@
#include <subdev/therm.h>
#include <subdev/timer.h>
#include <subdev/volt.h>
+#include <subdev/secboot.h>
#include <engine/bsp.h>
#include <engine/ce.h>
diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c
index 87c79ff2a..0a48de033 100644
--- a/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -27,7 +27,7 @@
#include <core/client.h>
#include <core/option.h>
-#include <core/secure_boot.h>
+#include <subdev/secboot.h>
#include <subdev/fb.h>
#include <subdev/mc.h>
#include <subdev/pmu.h>
diff --git a/drm/nouveau/nvkm/engine/gr/gm20b.c b/drm/nouveau/nvkm/engine/gr/gm20b.c
index 7872fb5e6..9f804c7ae 100644
--- a/drm/nouveau/nvkm/engine/gr/gm20b.c
+++ b/drm/nouveau/nvkm/engine/gr/gm20b.c
@@ -33,7 +33,7 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
u32 val;
/* Bypass MMU check for non-secure boot */
- if (!device->chip->secure_boot.managed_falcons) {
+ if (!device->secboot) {
nvkm_wr32(device, 0x100ce4, 0xffffffff);
if (nvkm_rd32(device, 0x100ce4) != 0xffffffff)
diff --git a/drm/nouveau/nvkm/subdev/Kbuild b/drm/nouveau/nvkm/subdev/Kbuild
index ee2c38f50..ec8c5eb30 100644
--- a/drm/nouveau/nvkm/subdev/Kbuild
+++ b/drm/nouveau/nvkm/subdev/Kbuild
@@ -15,6 +15,7 @@ include $(src)/nvkm/subdev/mmu/Kbuild
include $(src)/nvkm/subdev/mxm/Kbuild
include $(src)/nvkm/subdev/pci/Kbuild
include $(src)/nvkm/subdev/pmu/Kbuild
+include $(src)/nvkm/subdev/secboot/Kbuild
include $(src)/nvkm/subdev/therm/Kbuild
include $(src)/nvkm/subdev/timer/Kbuild
include $(src)/nvkm/subdev/volt/Kbuild
diff --git a/drm/nouveau/nvkm/subdev/secboot/Kbuild b/drm/nouveau/nvkm/subdev/secboot/Kbuild
new file mode 100644
index 000000000..920fdcb71
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/secboot/Kbuild
@@ -0,0 +1 @@
+nvkm-y += nvkm/subdev/secboot/base.o \ No newline at end of file
diff --git a/drm/nouveau/nvkm/core/secure_boot.c b/drm/nouveau/nvkm/subdev/secboot/base.c
index 52883170a..11bfd3a1a 100644
--- a/drm/nouveau/nvkm/core/secure_boot.c
+++ b/drm/nouveau/nvkm/subdev/secboot/base.c
@@ -80,14 +80,16 @@
*
*/
-#include <core/secure_boot.h>
#include <core/gpuobj.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
+#include <subdev/secboot.h>
#include <linux/mutex.h>
+#include "priv.h"
+
enum {
FALCON_DMAIDX_UCODE = 0,
FALCON_DMAIDX_VIRT = 1,
@@ -416,12 +418,6 @@ struct acr_load_header {
/**
* Contains the whole secure boot state, allowing it to be performed as needed
- * @falcon_id: falcon that will perform secure boot
- * @wpr_addr: physical address of the WPR region
- * @wpr_size: size in bytes of the WPR region
- * @ls_blob: LS blob of all the LS firmwares, signatures, bootloaders
- * @ls_blob_size: size of the LS blob
- * @ls_blob_nb_regions: number of LS firmwares that will be loaded
* @acr_blob: HS blob
* @acr_blob_vma: mapping of the HS blob into the secure falcon's VM
* @acr_bl_desc: bootloader descriptor of the HS blob
@@ -431,24 +427,10 @@ struct acr_load_header {
* @vm: address space used by the HS falcon
*/
struct secure_boot {
- u32 falcon_id;
- u64 wpr_addr;
- u32 wpr_size;
u32 base;
- /* LS FWs, to be loaded by the HS ACR */
- struct nvkm_gpuobj *ls_blob;
- u32 ls_blob_size;
- u16 ls_blob_nb_regions;
-
- /* HS FW */
- struct nvkm_gpuobj *acr_blob;
- struct nvkm_vma acr_blob_vma;
struct flcn_bl_dmem_desc acr_bl_desc;
- /* HS bootloader */
- void *hsbl_blob;
-
/* Instance block & address space */
struct nvkm_gpuobj *inst;
struct nvkm_gpuobj *pgd;
@@ -677,7 +659,7 @@ lsf_ucode_img_load_gpccs(struct nvkm_device *device, struct lsf_ucode_img *img)
*/
static void
lsf_ucode_img_populate_bl_desc(struct lsf_ucode_img *img,
- struct secure_boot *sb,
+ struct nvkm_secboot *sb,
struct flcn_bl_dmem_desc *desc)
{
struct ls_ucode_desc *pdesc = &img->ucode_desc;
@@ -874,7 +856,7 @@ lsf_ucode_mgr_add_img(struct lsf_ucode_mgr *mgr, struct lsf_ucode_img *img)
* lsf_mgr_fill_headers - fill the WPR and LSB headers of all managed images
*/
static void
-lsf_ucode_mgr_fill_headers(struct secure_boot *sb, struct lsf_ucode_mgr *mgr)
+lsf_ucode_mgr_fill_headers(struct nvkm_secboot *sb, struct lsf_ucode_mgr *mgr)
{
struct lsf_ucode_img *img;
u32 offset;
@@ -905,7 +887,7 @@ static void
lsf_ucode_mgr_write_wpr(struct nvkm_device *device, struct lsf_ucode_mgr *mgr,
struct nvkm_gpuobj *wpr_blob)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
struct lsf_ucode_img *img;
u32 pos = 0;
@@ -949,19 +931,19 @@ lsf_ucode_mgr_write_wpr(struct nvkm_device *device, struct lsf_ucode_mgr *mgr,
* will be copied into the WPR region by the HS firmware.
*/
static int
-sb_prepare_ls_blob(struct nvkm_device *device)
+sb_prepare_ls_blob(struct nvkm_secboot *sb)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_device *device = sb->subdev.device;
struct lsf_ucode_mgr mgr;
int falcon_id;
int err;
lsf_ucode_mgr_init(&mgr);
- sb->falcon_id = device->chip->secure_boot.boot_falcon;
+ sb->falcon_id = sb->func->boot_falcon;
/* Load all LS blobs */
- for_each_set_bit(falcon_id, &device->chip->secure_boot.managed_falcons,
+ for_each_set_bit(falcon_id, &sb->func->managed_falcons,
LSF_FALCON_ID_END) {
struct lsf_ucode_img *img;
@@ -1014,14 +996,6 @@ cleanup:
return err;
}
-static void
-sb_cleanup_ls_blob(struct nvkm_device *device)
-{
- struct secure_boot *sb = device->secure_boot_state;
-
- nvkm_gpuobj_del(&sb->ls_blob);
-}
-
/*
* High-secure blob creation
*/
@@ -1105,7 +1079,7 @@ struct hsflcn_acr_desc {
static void
hsf_img_patch_desc(struct nvkm_device *device, void *acr_image)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
struct hs_bin_hdr *hsbin_hdr = acr_image;
struct acr_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset;
struct acr_load_header *load_hdr = acr_image + fw_hdr->hdr_offset;
@@ -1162,7 +1136,8 @@ hsf_img_populate_bl_desc(void *acr_image, struct flcn_bl_dmem_desc *bl_desc)
static int
sb_prepare_hs_blob(struct nvkm_device *device)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
+ struct secure_boot *dsb = device->secure_boot_state;
void *acr_image;
struct hs_bin_hdr *hsbin_hdr;
u32 img_size;
@@ -1177,7 +1152,7 @@ sb_prepare_hs_blob(struct nvkm_device *device)
hsf_img_patch_desc(device, acr_image);
/* Generate HS BL descriptor */
- hsf_img_populate_bl_desc(acr_image, &sb->acr_bl_desc);
+ hsf_img_populate_bl_desc(acr_image, &dsb->acr_bl_desc);
/* Create ACR blob and copy HS data to it */
hsbin_hdr = acr_image;
@@ -1198,14 +1173,6 @@ cleanup:
return err;
}
-static void
-sb_cleanup_hs_blob(struct nvkm_device *device)
-{
- struct secure_boot *sb = device->secure_boot_state;
-
- nvkm_gpuobj_del(&sb->acr_blob);
-}
-
/*
* High-secure bootloader blob creation
*/
@@ -1213,7 +1180,7 @@ sb_cleanup_hs_blob(struct nvkm_device *device)
static int
sb_prepare_hsbl_blob(struct nvkm_device *device)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
if (!sb->hsbl_blob) {
sb->hsbl_blob = sb_load_firmware(device, "acr_bl", 0);
@@ -1228,15 +1195,6 @@ sb_prepare_hsbl_blob(struct nvkm_device *device)
return 0;
}
-static void
-sb_cleanup_hsbl_blob(struct nvkm_device *device)
-{
- struct secure_boot *sb = device->secure_boot_state;
-
- kfree(sb->hsbl_blob);
- sb->hsbl_blob = NULL;
-}
-
/*
* Falcon/PMU utility functions
*/
@@ -1453,10 +1411,11 @@ static void
sb_load_hs_bl(struct nvkm_device *device)
{
struct secure_boot *sb = device->secure_boot_state;
- struct hs_bin_hdr *hdr = sb->hsbl_blob;
- struct hsflcn_bl_desc *hsbl_desc = sb->hsbl_blob + hdr->header_offset;
- u32 acr_blob_vma_base = lower_32_bits(sb->acr_blob_vma.offset);
- void *hsbl_code = sb->hsbl_blob + hdr->data_offset;
+ struct nvkm_secboot *nsb = device->secboot;
+ struct hs_bin_hdr *hdr = nsb->hsbl_blob;
+ struct hsflcn_bl_desc *hsbl_desc = nsb->hsbl_blob + hdr->header_offset;
+ u32 acr_blob_vma_base = lower_32_bits(nsb->acr_blob_vma.offset);
+ void *hsbl_code = nsb->hsbl_blob + hdr->data_offset;
u32 code_size = ALIGN(hsbl_desc->bl_code_size, 256);
u32 dst_blk;
u32 tag;
@@ -1497,8 +1456,9 @@ static int
sb_start(struct nvkm_device *device)
{
struct secure_boot *sb = device->secure_boot_state;
- struct hs_bin_hdr *hdr = sb->hsbl_blob;
- struct hsflcn_bl_desc *hsbl_desc = sb->hsbl_blob + hdr->header_offset;
+ struct nvkm_secboot *nsb = device->secboot;
+ struct hs_bin_hdr *hdr = nsb->hsbl_blob;
+ struct hsflcn_bl_desc *hsbl_desc = nsb->hsbl_blob + hdr->header_offset;
/* virtual start address for boot vector */
u32 virt_addr = hsbl_desc->bl_start_tag << 8;
@@ -1520,11 +1480,12 @@ sb_start(struct nvkm_device *device)
static int
sb_execute(struct nvkm_device *device)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
+ struct secure_boot *psb = device->secure_boot_state;
int err;
/* Map the HS firmware so the HS bootloader can see it */
- err = nvkm_gpuobj_map(sb->acr_blob, sb->vm, NV_MEM_ACCESS_RW,
+ err = nvkm_gpuobj_map(sb->acr_blob, psb->vm, NV_MEM_ACCESS_RW,
&sb->acr_blob_vma);
if (err)
return err;
@@ -1578,38 +1539,17 @@ const char *managed_falcons_names[] = {
int
nvkm_secure_boot(struct nvkm_device *device)
{
- struct secure_boot *sb;
+ struct nvkm_secboot *sb = device->secboot;
unsigned long falcon_id;
int err;
- sb = device->secure_boot_state;
+ printk("SEC BOOT BOOTING FALCONS\n");
nvdev_debug(device, "performing secure boot of:\n");
- for_each_set_bit(falcon_id, &device->chip->secure_boot.managed_falcons,
+ for_each_set_bit(falcon_id, &sb->func->managed_falcons,
LSF_FALCON_ID_END)
nvdev_debug(device, "- %s\n", managed_falcons_names[falcon_id]);
- /* Load all the LS firmwares and prepare the blob */
- if (!sb->ls_blob) {
- err = sb_prepare_ls_blob(device);
- if (err)
- return err;
- }
-
- /* Load the HS firmware for the performing falcon */
- if (!sb->acr_blob) {
- err = sb_prepare_hs_blob(device);
- if (err)
- return err;
- }
-
- /* Load the HS firmware bootloader */
- if (!sb->hsbl_blob) {
- err = sb_prepare_hsbl_blob(device);
- if (err)
- return err;
- }
-
/*
* Run the HS bootloader. It will load the HS firmware and then run it.
* Once this returns, the LS firmwares will be loaded into the managed
@@ -1689,7 +1629,7 @@ sb_cleanup_vm(struct nvkm_device *device)
static int
sb_tegra_read_wpr(struct nvkm_device *device)
{
- struct secure_boot *sb = device->secure_boot_state;
+ struct nvkm_secboot *sb = device->secboot;
void __iomem *mc;
u32 cfg;
@@ -1733,7 +1673,7 @@ sb_tegra_read_wpr(struct nvkm_device *device)
* Prepare secure boot for a device. This will not load the firmwares yet,
* firmwares are loaded and cached upon the first call to nvkm_secure_boot().
*/
-int
+static int
nvkm_secure_boot_init(struct nvkm_device *device)
{
struct secure_boot *sb;
@@ -1762,7 +1702,7 @@ nvkm_secure_boot_init(struct nvkm_device *device)
goto error_free;
}
- switch (device->chip->secure_boot.boot_falcon) {
+ switch (device->secboot->func->boot_falcon) {
case LSF_FALCON_ID_PMU:
sb->base = 0x10a000;
break;
@@ -1787,30 +1727,120 @@ error:
return err;
}
-/**
- * nvkm_secure_boot_fini() - cleanup secure boot state for a device
- *
- * Frees all the memory used by secure boot.
- */
-void
-nvkm_secure_boot_fini(struct nvkm_device *device)
+bool
+nvkm_is_secure(struct nvkm_device *device, unsigned long falcon_id)
{
- struct secure_boot *sb = device->secure_boot_state;
+ return device->secboot->func->managed_falcons & BIT(falcon_id);
+}
- if (!sb)
- return;
+static int
+nvkm_secboot_oneinit(struct nvkm_subdev *subdev)
+{
+ struct nvkm_secboot *dsb = nvkm_secboot(subdev);
+ struct secure_boot *sb;
+ int err;
+
+ printk("SEC BOOT ONE INIT\n");
+
+ err = nvkm_secure_boot_init(dsb->subdev.device);
+ if (err)
+ return err;
+
+ sb = subdev->device->secure_boot_state;
+
+ /* Load and prepare the managed falcon's firmwares */
+ err = sb_prepare_ls_blob(dsb);
+ if (err)
+ return err;
+
+ /* Load the HS firmware for the performing falcon */
+ err = sb_prepare_hs_blob(subdev->device);
+ if (err)
+ return err;
+
+ /* Load the HS firmware bootloader */
+ err = sb_prepare_hsbl_blob(subdev->device);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static void *
+nvkm_secboot_dtor(struct nvkm_subdev *subdev)
+{
+ struct nvkm_secboot *sb = nvkm_secboot(subdev);
+
+ printk("SEC BOOT DTOR\n");
if (sb->hsbl_blob)
- sb_cleanup_hsbl_blob(device);
+ kfree(sb->hsbl_blob);
if (sb->acr_blob)
- sb_cleanup_hs_blob(device);
+ nvkm_gpuobj_del(&sb->acr_blob);
if (sb->ls_blob)
- sb_cleanup_ls_blob(device);
+ nvkm_gpuobj_del(&sb->ls_blob);
- sb_cleanup_vm(device);
+ sb_cleanup_vm(subdev->device);
- kfree(sb);
- device->secure_boot_state = NULL;
+ return sb;
}
+
+static const struct nvkm_subdev_func
+nvkm_secboot = {
+ .oneinit = nvkm_secboot_oneinit,
+ .dtor = nvkm_secboot_dtor,
+};
+
+int
+nvkm_secboot_new_(const struct nvkm_secboot_func *func,
+ struct nvkm_device *device, int index,
+ struct nvkm_secboot **psb)
+{
+ struct nvkm_secboot *sb;
+
+ if (!(sb = *psb = kzalloc(sizeof(*sb), GFP_KERNEL)))
+ return -ENOMEM;
+
+ nvkm_subdev_ctor(&nvkm_secboot, device, index, 0, &sb->subdev);
+ sb->func = func;
+
+ return 0;
+}
+
+static int
+gm200_prepare_blobs(struct nvkm_secboot *sb)
+{
+ printk("SEC BOOT PREPARE BLOBS\n");
+
+ return 0;
+}
+
+static const struct nvkm_secboot_func
+gm200_secboot = {
+ .prepare_blobs = gm200_prepare_blobs,
+ .managed_falcons = BIT(LSF_FALCON_ID_FECS) | BIT(LSF_FALCON_ID_GPCCS),
+ .boot_falcon = LSF_FALCON_ID_PMU,
+};
+
+int
+gm200_secboot_new(struct nvkm_device *device, int index,
+ struct nvkm_secboot **secboot)
+{
+ return nvkm_secboot_new_(&gm200_secboot, device, index, secboot);
+}
+
+static const struct nvkm_secboot_func
+gm20b_secboot = {
+ .prepare_blobs = gm200_prepare_blobs,
+ .managed_falcons = BIT(LSF_FALCON_ID_FECS),
+ .boot_falcon = LSF_FALCON_ID_PMU,
+};
+
+int
+gm20b_secboot_new(struct nvkm_device *device, int index,
+ struct nvkm_secboot **secboot)
+{
+ return nvkm_secboot_new_(&gm20b_secboot, device, index, secboot);
+} \ No newline at end of file
diff --git a/drm/nouveau/nvkm/subdev/secboot/priv.h b/drm/nouveau/nvkm/subdev/secboot/priv.h
new file mode 100644
index 000000000..bed4cce99
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/secboot/priv.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, 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_PRIV_H__
+#define __NVKM_SECBOOT_PRIV_H__
+#define nvkm_secboot(p) container_of((p), struct nvkm_secboot, subdev)
+#include <subdev/secboot.h>
+
+int nvkm_secboot_new_(const struct nvkm_secboot_func *, struct nvkm_device *,
+ int index, struct nvkm_secboot **);
+
+struct nvkm_secboot_func {
+ int (*prepare_blobs)(struct nvkm_secboot *);
+ /* Bit-mask of IDs of managed falcons */
+ unsigned long managed_falcons;
+ /* ID of the falcon that will perform secure boot */
+ unsigned long boot_falcon;
+};
+
+#endif