Skip to content

Commit 72ea783

Browse files
amd-morriszhangalexdeucher
authored andcommitted
drm/amdgpu: add debugfs for spirom IFWI dump
Expose the debugfs file node for user space to dump the IFWI image on spirom. For one transaction between PSP and host, it will read out the images on both active and inactive partitions so a buffer with two times the size of maximum IFWI image (currently 16MByte) is needed. v2: move the vbios gfl macros to the common header and rename the bo triplet struct to spirom_bo for this specific usage (Hawking) v3: return directly the result of last command execution (Lijo) Signed-off-by: Shiwu Zhang <shiwu.zhang@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 64db767 commit 72ea783

4 files changed

Lines changed: 168 additions & 10 deletions

File tree

drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
21052105
amdgpu_rap_debugfs_init(adev);
21062106
amdgpu_securedisplay_debugfs_init(adev);
21072107
amdgpu_fw_attestation_debugfs_init(adev);
2108+
amdgpu_psp_debugfs_init(adev);
21082109

21092110
debugfs_create_file("amdgpu_evict_vram", 0400, root, adev,
21102111
&amdgpu_evict_vram_fops);

drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4186,6 +4186,110 @@ const struct attribute_group amdgpu_flash_attr_group = {
41864186
.is_visible = amdgpu_flash_attr_is_visible,
41874187
};
41884188

4189+
#if defined(CONFIG_DEBUG_FS)
4190+
static int psp_read_spirom_debugfs_open(struct inode *inode, struct file *filp)
4191+
{
4192+
struct amdgpu_device *adev = filp->f_inode->i_private;
4193+
struct spirom_bo *bo_triplet;
4194+
int ret;
4195+
4196+
/* serialize the open() file calling */
4197+
if (!mutex_trylock(&adev->psp.mutex))
4198+
return -EBUSY;
4199+
4200+
/*
4201+
* make sure only one userpace process is alive for dumping so that
4202+
* only one memory buffer of AMD_VBIOS_FILE_MAX_SIZE * 2 is consumed.
4203+
* let's say the case where one process try opening the file while
4204+
* another one has proceeded to read or release. In this way, eliminate
4205+
* the use of mutex for read() or release() callback as well.
4206+
*/
4207+
if (adev->psp.spirom_dump_trip) {
4208+
mutex_unlock(&adev->psp.mutex);
4209+
return -EBUSY;
4210+
}
4211+
4212+
bo_triplet = kzalloc(sizeof(struct spirom_bo), GFP_KERNEL);
4213+
if (!bo_triplet) {
4214+
mutex_unlock(&adev->psp.mutex);
4215+
return -ENOMEM;
4216+
}
4217+
4218+
ret = amdgpu_bo_create_kernel(adev, AMD_VBIOS_FILE_MAX_SIZE_B * 2,
4219+
AMDGPU_GPU_PAGE_SIZE,
4220+
AMDGPU_GEM_DOMAIN_GTT,
4221+
&bo_triplet->bo,
4222+
&bo_triplet->mc_addr,
4223+
&bo_triplet->cpu_addr);
4224+
if (ret)
4225+
goto rel_trip;
4226+
4227+
ret = psp_dump_spirom(&adev->psp, bo_triplet->mc_addr);
4228+
if (ret)
4229+
goto rel_bo;
4230+
4231+
adev->psp.spirom_dump_trip = bo_triplet;
4232+
mutex_unlock(&adev->psp.mutex);
4233+
return 0;
4234+
rel_bo:
4235+
amdgpu_bo_free_kernel(&bo_triplet->bo, &bo_triplet->mc_addr,
4236+
&bo_triplet->cpu_addr);
4237+
rel_trip:
4238+
kfree(bo_triplet);
4239+
mutex_unlock(&adev->psp.mutex);
4240+
dev_err(adev->dev, "Trying IFWI dump fails, err = %d\n", ret);
4241+
return ret;
4242+
}
4243+
4244+
static ssize_t psp_read_spirom_debugfs_read(struct file *filp, char __user *buf, size_t size,
4245+
loff_t *pos)
4246+
{
4247+
struct amdgpu_device *adev = filp->f_inode->i_private;
4248+
struct spirom_bo *bo_triplet = adev->psp.spirom_dump_trip;
4249+
4250+
if (!bo_triplet)
4251+
return -EINVAL;
4252+
4253+
return simple_read_from_buffer(buf,
4254+
size,
4255+
pos, bo_triplet->cpu_addr,
4256+
AMD_VBIOS_FILE_MAX_SIZE_B * 2);
4257+
}
4258+
4259+
static int psp_read_spirom_debugfs_release(struct inode *inode, struct file *filp)
4260+
{
4261+
struct amdgpu_device *adev = filp->f_inode->i_private;
4262+
struct spirom_bo *bo_triplet = adev->psp.spirom_dump_trip;
4263+
4264+
if (bo_triplet) {
4265+
amdgpu_bo_free_kernel(&bo_triplet->bo, &bo_triplet->mc_addr,
4266+
&bo_triplet->cpu_addr);
4267+
kfree(bo_triplet);
4268+
}
4269+
4270+
adev->psp.spirom_dump_trip = NULL;
4271+
return 0;
4272+
}
4273+
4274+
static const struct file_operations psp_dump_spirom_debugfs_ops = {
4275+
.owner = THIS_MODULE,
4276+
.open = psp_read_spirom_debugfs_open,
4277+
.read = psp_read_spirom_debugfs_read,
4278+
.release = psp_read_spirom_debugfs_release,
4279+
.llseek = default_llseek,
4280+
};
4281+
#endif
4282+
4283+
void amdgpu_psp_debugfs_init(struct amdgpu_device *adev)
4284+
{
4285+
#if defined(CONFIG_DEBUG_FS)
4286+
struct drm_minor *minor = adev_to_drm(adev)->primary;
4287+
4288+
debugfs_create_file_size("psp_spirom_dump", 0444, minor->debugfs_root,
4289+
adev, &psp_dump_spirom_debugfs_ops, AMD_VBIOS_FILE_MAX_SIZE_B * 2);
4290+
#endif
4291+
}
4292+
41894293
const struct amd_ip_funcs psp_ip_funcs = {
41904294
.name = "psp",
41914295
.early_init = psp_early_init,

drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@
3939
#define PSP_TMR_ALIGNMENT 0x100000
4040
#define PSP_FW_NAME_LEN 0x24
4141

42+
/* VBIOS gfl defines */
43+
#define MBOX_READY_MASK 0x80000000
44+
#define MBOX_STATUS_MASK 0x0000FFFF
45+
#define MBOX_COMMAND_MASK 0x00FF0000
46+
#define MBOX_READY_FLAG 0x80000000
47+
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2
48+
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3
49+
#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4
50+
#define C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_LO 0xf
51+
#define C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI 0x10
52+
#define C2PMSG_CMD_SPI_GET_FLASH_IMAGE 0x11
53+
4254
extern const struct attribute_group amdgpu_flash_attr_group;
4355

4456
enum psp_shared_mem_size {
@@ -138,6 +150,7 @@ struct psp_funcs {
138150
int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
139151
int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver);
140152
int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
153+
int (*dump_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
141154
int (*vbflash_stat)(struct psp_context *psp);
142155
int (*fatal_error_recovery_quirk)(struct psp_context *psp);
143156
bool (*get_ras_capability)(struct psp_context *psp);
@@ -322,6 +335,14 @@ struct psp_runtime_scpm_entry {
322335
enum psp_runtime_scpm_authentication scpm_status;
323336
};
324337

338+
#if defined(CONFIG_DEBUG_FS)
339+
struct spirom_bo {
340+
struct amdgpu_bo *bo;
341+
uint64_t mc_addr;
342+
void *cpu_addr;
343+
};
344+
#endif
345+
325346
struct psp_context {
326347
struct amdgpu_device *adev;
327348
struct psp_ring km_ring;
@@ -409,6 +430,9 @@ struct psp_context {
409430
char *vbflash_tmp_buf;
410431
size_t vbflash_image_size;
411432
bool vbflash_done;
433+
#if defined(CONFIG_DEBUG_FS)
434+
struct spirom_bo *spirom_dump_trip;
435+
#endif
412436
};
413437

414438
struct amdgpu_psp_funcs {
@@ -467,6 +491,10 @@ struct amdgpu_psp_funcs {
467491
((psp)->funcs->update_spirom ? \
468492
(psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL)
469493

494+
#define psp_dump_spirom(psp, fw_pri_mc_addr) \
495+
((psp)->funcs->dump_spirom ? \
496+
(psp)->funcs->dump_spirom((psp), fw_pri_mc_addr) : -EINVAL)
497+
470498
#define psp_vbflash_status(psp) \
471499
((psp)->funcs->vbflash_stat ? \
472500
(psp)->funcs->vbflash_stat((psp)) : -EINVAL)
@@ -578,6 +606,7 @@ int psp_config_sq_perfmon(struct psp_context *psp, uint32_t xcp_id,
578606
bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev);
579607
int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val,
580608
enum psp_reg_prog_id id);
609+
void amdgpu_psp_debugfs_init(struct amdgpu_device *adev);
581610

582611

583612
#endif

drivers/gpu/drm/amd/amdgpu/psp_v13_0.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,6 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_4_ta.bin");
7171
/* Retry times for vmbx ready wait */
7272
#define PSP_VMBX_POLLING_LIMIT 3000
7373

74-
/* VBIOS gfl defines */
75-
#define MBOX_READY_MASK 0x80000000
76-
#define MBOX_STATUS_MASK 0x0000FFFF
77-
#define MBOX_COMMAND_MASK 0x00FF0000
78-
#define MBOX_READY_FLAG 0x80000000
79-
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2
80-
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3
81-
#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4
82-
8374
/* memory training timeout define */
8475
#define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000
8576

@@ -741,7 +732,8 @@ static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd)
741732
/* Ring the doorbell */
742733
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1);
743734

744-
if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE)
735+
if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE ||
736+
cmd == C2PMSG_CMD_SPI_GET_FLASH_IMAGE)
745737
ret = psp_wait_for_spirom_update(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115),
746738
MBOX_READY_FLAG, MBOX_READY_MASK, PSP_SPIROM_UPDATE_TIMEOUT);
747739
else
@@ -797,6 +789,37 @@ static int psp_v13_0_update_spirom(struct psp_context *psp,
797789
return 0;
798790
}
799791

792+
static int psp_v13_0_dump_spirom(struct psp_context *psp,
793+
uint64_t fw_pri_mc_addr)
794+
{
795+
struct amdgpu_device *adev = psp->adev;
796+
int ret;
797+
798+
/* Confirm PSP is ready to start */
799+
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115),
800+
MBOX_READY_FLAG, MBOX_READY_MASK, false);
801+
if (ret) {
802+
dev_err(adev->dev, "PSP Not ready to start processing, ret = %d", ret);
803+
return ret;
804+
}
805+
806+
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr));
807+
808+
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_LO);
809+
if (ret)
810+
return ret;
811+
812+
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr));
813+
814+
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI);
815+
if (ret)
816+
return ret;
817+
818+
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_FLASH_IMAGE);
819+
820+
return ret;
821+
}
822+
800823
static int psp_v13_0_vbflash_status(struct psp_context *psp)
801824
{
802825
struct amdgpu_device *adev = psp->adev;
@@ -929,6 +952,7 @@ static const struct psp_funcs psp_v13_0_funcs = {
929952
.load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw,
930953
.read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw,
931954
.update_spirom = psp_v13_0_update_spirom,
955+
.dump_spirom = psp_v13_0_dump_spirom,
932956
.vbflash_stat = psp_v13_0_vbflash_status,
933957
.fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk,
934958
.get_ras_capability = psp_v13_0_get_ras_capability,

0 commit comments

Comments
 (0)