@@ -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+
41894293const struct amd_ip_funcs psp_ip_funcs = {
41904294 .name = "psp" ,
41914295 .early_init = psp_early_init ,
0 commit comments