Commit 8f491c89 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs

drm/nouveau/secboot: generate HS BL descriptor in hook

Use the HS hook to completely generate the HS BL descriptor, similarly
to what is done in the LS hook, instead of (arbitrarily) using the
acr_v1 format as an intermediate.

This allows us to make the bootloader descriptor structures private to
each implementation, resulting in a cleaner an more consistent design.
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent e781ff91
...@@ -88,41 +88,28 @@ gm20b_secboot_prepare_blobs(struct gm200_secboot *gsb) ...@@ -88,41 +88,28 @@ gm20b_secboot_prepare_blobs(struct gm200_secboot *gsb)
return 0; return 0;
} }
/**
* gm20b_secboot_fixup_bl_desc - adapt BL descriptor to format used by GM20B FW
*
* There is only a slight format difference (DMA addresses being 32-bits and
* 256B-aligned) to address.
*/
static void static void
gm20b_secboot_fixup_bl_desc(const struct gm200_flcn_bl_desc *desc, void *ret) gm20b_secboot_generate_bl_desc(const struct hsf_load_header *load_hdr,
void *_bl_desc, u64 offset)
{ {
struct gm20b_flcn_bl_desc *gdesc = ret; struct gm20b_flcn_bl_desc *bl_desc = _bl_desc;
u64 addr;
memset(bl_desc, 0, sizeof(*bl_desc));
memcpy(gdesc->reserved, desc->reserved, sizeof(gdesc->reserved)); bl_desc->ctx_dma = FALCON_DMAIDX_VIRT;
memcpy(gdesc->signature, desc->signature, sizeof(gdesc->signature)); bl_desc->non_sec_code_off = load_hdr->non_sec_code_off;
gdesc->ctx_dma = desc->ctx_dma; bl_desc->non_sec_code_size = load_hdr->non_sec_code_size;
addr = desc->code_dma_base.hi; bl_desc->sec_code_off = load_hdr->app[0].sec_code_off;
addr <<= 32; bl_desc->sec_code_size = load_hdr->app[0].sec_code_size;
addr |= desc->code_dma_base.lo; bl_desc->code_entry_point = 0;
gdesc->code_dma_base = lower_32_bits(addr >> 8); bl_desc->code_dma_base = offset >> 8;
gdesc->non_sec_code_off = desc->non_sec_code_off; bl_desc->data_dma_base = (offset + load_hdr->data_dma_base) >> 8;
gdesc->non_sec_code_size = desc->non_sec_code_size; bl_desc->data_size = load_hdr->data_size;
gdesc->sec_code_off = desc->sec_code_off;
gdesc->sec_code_size = desc->sec_code_size;
gdesc->code_entry_point = desc->code_entry_point;
addr = desc->data_dma_base.hi;
addr <<= 32;
addr |= desc->data_dma_base.lo;
gdesc->data_dma_base = lower_32_bits(addr >> 8);
gdesc->data_size = desc->data_size;
} }
static const struct gm200_secboot_func static const struct gm200_secboot_func
gm20b_secboot_func = { gm20b_secboot_func = {
.bl_desc_size = sizeof(struct gm20b_flcn_bl_desc), .bl_desc_size = sizeof(struct gm20b_flcn_bl_desc),
.fixup_bl_desc = gm20b_secboot_fixup_bl_desc, .generate_bl_desc = gm20b_secboot_generate_bl_desc,
.prepare_blobs = gm20b_secboot_prepare_blobs, .prepare_blobs = gm20b_secboot_prepare_blobs,
}; };
......
...@@ -214,46 +214,39 @@ struct flcn_u64 { ...@@ -214,46 +214,39 @@ struct flcn_u64 {
u32 lo; u32 lo;
u32 hi; u32 hi;
}; };
static inline u64 flcn64_to_u64(const struct flcn_u64 f) static inline u64 flcn64_to_u64(const struct flcn_u64 f)
{ {
return ((u64)f.hi) << 32 | f.lo; return ((u64)f.hi) << 32 | f.lo;
} }
static inline struct flcn_u64 u64_to_flcn64(u64 u)
{
struct flcn_u64 ret;
ret.hi = upper_32_bits(u);
ret.lo = lower_32_bits(u);
return ret;
}
#define GM200_ACR_MAX_APPS 8
struct hsf_load_header_app {
u32 sec_code_off;
u32 sec_code_size;
};
/** /**
* struct gm200_flcn_bl_desc - DMEM bootloader descriptor * struct hsf_load_header - HS firmware load header
* @signature: 16B signature for secure code. 0s if no secure code
* @ctx_dma: DMA context to be used by BL while loading code/data
* @code_dma_base: 256B-aligned Physical FB Address where code is located
* (falcon's $xcbase register)
* @non_sec_code_off: offset from code_dma_base where the non-secure code is
* located. The offset must be multiple of 256 to help perf
* @non_sec_code_size: the size of the nonSecure code part.
* @sec_code_off: offset from code_dma_base where the secure code is
* located. The offset must be multiple of 256 to help perf
* @sec_code_size: offset from code_dma_base where the secure code is
* located. The offset must be multiple of 256 to help perf
* @code_entry_point: code entry point which will be invoked by BL after
* code is loaded.
* @data_dma_base: 256B aligned Physical FB Address where data is located.
* (falcon's $xdbase register)
* @data_size: size of data block. Should be multiple of 256B
*
* Structure used by the bootloader to load the rest of the code. This has
* to be filled by host and copied into DMEM at offset provided in the
* hsflcn_bl_desc.bl_desc_dmem_load_off.
*/ */
struct gm200_flcn_bl_desc { struct hsf_load_header {
u32 reserved[4];
u32 signature[4];
u32 ctx_dma;
struct flcn_u64 code_dma_base;
u32 non_sec_code_off; u32 non_sec_code_off;
u32 non_sec_code_size; u32 non_sec_code_size;
u32 sec_code_off; u32 data_dma_base;
u32 sec_code_size;
u32 code_entry_point;
struct flcn_u64 data_dma_base;
u32 data_size; u32 data_size;
u32 num_apps;
struct hsf_load_header_app app[0];
}; };
/** /**
...@@ -319,11 +312,17 @@ struct gm200_secboot { ...@@ -319,11 +312,17 @@ struct gm200_secboot {
* on Tegra the HS FW copies the LS blob into the fixed WPR instead * on Tegra the HS FW copies the LS blob into the fixed WPR instead
*/ */
struct nvkm_gpuobj *acr_load_blob; struct nvkm_gpuobj *acr_load_blob;
struct gm200_flcn_bl_desc acr_load_bl_desc; struct {
struct hsf_load_header load_bl_header;
struct hsf_load_header_app __load_apps[GM200_ACR_MAX_APPS];
};
/* HS FW - unlock WPR region (dGPU only) */ /* HS FW - unlock WPR region (dGPU only) */
struct nvkm_gpuobj *acr_unload_blob; struct nvkm_gpuobj *acr_unload_blob;
struct gm200_flcn_bl_desc acr_unload_bl_desc; struct {
struct hsf_load_header unload_bl_header;
struct hsf_load_header_app __unload_apps[GM200_ACR_MAX_APPS];
};
/* HS bootloader */ /* HS bootloader */
void *hsbl_blob; void *hsbl_blob;
...@@ -353,9 +352,9 @@ struct gm200_secboot { ...@@ -353,9 +352,9 @@ struct gm200_secboot {
/** /**
* Contains functions we wish to abstract between GM200-like implementations * Contains functions we wish to abstract between GM200-like implementations
* @bl_desc_size: size of the BL descriptor used by this chip. * @bl_desc_size: size of the BL descriptor used by this chip.
* @fixup_bl_desc: hook that generates the proper BL descriptor format from * @generate_bl_desc: hook that generates the proper BL descriptor format from
* the generic GM200 format into a data array of size * the hsf_load_header format into a preallocated array of
* bl_desc_size * size bl_desc_size
* @prepare_blobs: prepares the various blobs needed for secure booting * @prepare_blobs: prepares the various blobs needed for secure booting
*/ */
struct gm200_secboot_func { struct gm200_secboot_func {
...@@ -365,7 +364,7 @@ struct gm200_secboot_func { ...@@ -365,7 +364,7 @@ struct gm200_secboot_func {
* callback is called on it * callback is called on it
*/ */
u32 bl_desc_size; u32 bl_desc_size;
void (*fixup_bl_desc)(const struct gm200_flcn_bl_desc *, void *); void (*generate_bl_desc)(const struct hsf_load_header *, void *, u64);
int (*prepare_blobs)(struct gm200_secboot *); int (*prepare_blobs)(struct gm200_secboot *);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment