diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2015-12-18 17:24:48 +0900 |
---|---|---|
committer | Alexandre Courbot <acourbot@nvidia.com> | 2015-12-18 17:28:42 +0900 |
commit | 9bbfb71f9c93a7e2fef68dbed040d859de2a85f6 (patch) | |
tree | 9eebd08217a719fe550a3f84245f9f57f684c4dc | |
parent | c77a645cb43dbbb201ac7cc3392ca7bad2b39c58 (diff) | |
download | nouveau-9bbfb71f9c93a7e2fef68dbed040d859de2a85f6.tar.gz |
sb: move to subdev
-rw-r--r-- | drm/nouveau/include/nvkm/core/device.h | 10 | ||||
-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/Kbuild | 1 | ||||
-rw-r--r-- | drm/nouveau/nvkm/core/subdev.c | 1 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/device/base.c | 24 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/device/priv.h | 1 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/gr/gf100.c | 2 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/gr/gm20b.c | 2 | ||||
-rw-r--r-- | drm/nouveau/nvkm/subdev/Kbuild | 1 | ||||
-rw-r--r-- | drm/nouveau/nvkm/subdev/secboot/Kbuild | 1 | ||||
-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.h | 39 |
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 |