Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Shiwu Zhang and committed by
Alex Deucher
72ea7833 64db7670

+168 -10
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
··· 2105 2105 amdgpu_rap_debugfs_init(adev); 2106 2106 amdgpu_securedisplay_debugfs_init(adev); 2107 2107 amdgpu_fw_attestation_debugfs_init(adev); 2108 + amdgpu_psp_debugfs_init(adev); 2108 2109 2109 2110 debugfs_create_file("amdgpu_evict_vram", 0400, root, adev, 2110 2111 &amdgpu_evict_vram_fops);
+104
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 4186 4186 .is_visible = amdgpu_flash_attr_is_visible, 4187 4187 }; 4188 4188 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 + 4189 4293 const struct amd_ip_funcs psp_ip_funcs = { 4190 4294 .name = "psp", 4191 4295 .early_init = psp_early_init,
+29
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
··· 39 39 #define PSP_TMR_ALIGNMENT 0x100000 40 40 #define PSP_FW_NAME_LEN 0x24 41 41 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 + 42 54 extern const struct attribute_group amdgpu_flash_attr_group; 43 55 44 56 enum psp_shared_mem_size { ··· 150 138 int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr); 151 139 int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver); 152 140 int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); 141 + int (*dump_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); 153 142 int (*vbflash_stat)(struct psp_context *psp); 154 143 int (*fatal_error_recovery_quirk)(struct psp_context *psp); 155 144 bool (*get_ras_capability)(struct psp_context *psp); ··· 335 322 enum psp_runtime_scpm_authentication scpm_status; 336 323 }; 337 324 325 + #if defined(CONFIG_DEBUG_FS) 326 + struct spirom_bo { 327 + struct amdgpu_bo *bo; 328 + uint64_t mc_addr; 329 + void *cpu_addr; 330 + }; 331 + #endif 332 + 338 333 struct psp_context { 339 334 struct amdgpu_device *adev; 340 335 struct psp_ring km_ring; ··· 430 409 char *vbflash_tmp_buf; 431 410 size_t vbflash_image_size; 432 411 bool vbflash_done; 412 + #if defined(CONFIG_DEBUG_FS) 413 + struct spirom_bo *spirom_dump_trip; 414 + #endif 433 415 }; 434 416 435 417 struct amdgpu_psp_funcs { ··· 490 466 #define psp_update_spirom(psp, fw_pri_mc_addr) \ 491 467 ((psp)->funcs->update_spirom ? \ 492 468 (psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL) 469 + 470 + #define psp_dump_spirom(psp, fw_pri_mc_addr) \ 471 + ((psp)->funcs->dump_spirom ? \ 472 + (psp)->funcs->dump_spirom((psp), fw_pri_mc_addr) : -EINVAL) 493 473 494 474 #define psp_vbflash_status(psp) \ 495 475 ((psp)->funcs->vbflash_stat ? \ ··· 606 578 bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev); 607 579 int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val, 608 580 enum psp_reg_prog_id id); 581 + void amdgpu_psp_debugfs_init(struct amdgpu_device *adev); 609 582 610 583 611 584 #endif
+34 -10
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
··· 71 71 /* Retry times for vmbx ready wait */ 72 72 #define PSP_VMBX_POLLING_LIMIT 3000 73 73 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 - 83 74 /* memory training timeout define */ 84 75 #define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000 85 76 ··· 732 741 /* Ring the doorbell */ 733 742 WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1); 734 743 735 - if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE) 744 + if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE || 745 + cmd == C2PMSG_CMD_SPI_GET_FLASH_IMAGE) 736 746 ret = psp_wait_for_spirom_update(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), 737 747 MBOX_READY_FLAG, MBOX_READY_MASK, PSP_SPIROM_UPDATE_TIMEOUT); 738 748 else ··· 787 795 return ret; 788 796 789 797 return 0; 798 + } 799 + 800 + static int psp_v13_0_dump_spirom(struct psp_context *psp, 801 + uint64_t fw_pri_mc_addr) 802 + { 803 + struct amdgpu_device *adev = psp->adev; 804 + int ret; 805 + 806 + /* Confirm PSP is ready to start */ 807 + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), 808 + MBOX_READY_FLAG, MBOX_READY_MASK, false); 809 + if (ret) { 810 + dev_err(adev->dev, "PSP Not ready to start processing, ret = %d", ret); 811 + return ret; 812 + } 813 + 814 + WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr)); 815 + 816 + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_LO); 817 + if (ret) 818 + return ret; 819 + 820 + WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr)); 821 + 822 + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI); 823 + if (ret) 824 + return ret; 825 + 826 + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_FLASH_IMAGE); 827 + 828 + return ret; 790 829 } 791 830 792 831 static int psp_v13_0_vbflash_status(struct psp_context *psp) ··· 952 929 .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, 953 930 .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, 954 931 .update_spirom = psp_v13_0_update_spirom, 932 + .dump_spirom = psp_v13_0_dump_spirom, 955 933 .vbflash_stat = psp_v13_0_vbflash_status, 956 934 .fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk, 957 935 .get_ras_capability = psp_v13_0_get_ras_capability,