diff options
Diffstat (limited to 'mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c')
-rw-r--r-- | mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c b/mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c index 493e1c8..e371db2 100644 --- a/mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c +++ b/mali_kbase/csf/mali_kbase_csf_firmware_core_dump.c @@ -31,9 +31,6 @@ #include "mali_kbase_csf_firmware_core_dump.h" #include "backend/gpu/mali_kbase_pm_internal.h" -/* Page size in bytes in use by MCU. */ -#define FW_PAGE_SIZE 4096 - /* * FW image header core dump data format supported. * Currently only version 0.1 is supported. @@ -107,15 +104,6 @@ struct elf_prstatus32 { int pr_fpvalid; /* True if math copro being used. */ }; -/** - * struct fw_core_dump_data - Context for seq_file operations used on 'fw_core_dump' - * debugfs file. - * @kbdev: Instance of a GPU platform device that implements a CSF interface. - */ -struct fw_core_dump_data { - struct kbase_device *kbdev; -}; - /* * struct fw_core_dump_seq_off - Iterator for seq_file operations used on 'fw_core_dump' * debugfs file. @@ -405,7 +393,7 @@ static unsigned int fw_core_dump_create_prstatus_note(char *name, struct elf_prs * * 0 - success * * -ENOMEM - not enough memory for allocating ELF32 note */ -static int fw_core_dump_write_elf_header(struct seq_file *m) +int fw_core_dump_write_elf_header(struct seq_file *m) { struct elf32_hdr hdr; struct elf32_phdr phdr; @@ -496,13 +484,48 @@ static int fw_core_dump_write_elf_header(struct seq_file *m) return 0; } +#define MAX_FW_CORE_DUMP_HEADER_SIZE (1 << 14) + +/** + * get_fw_core_dump_size - Get firmware core dump size + * @kbdev: Instance of a GPU platform device that implements a CSF interface. + * + * Return: size on success, -1 otherwise. + */ +size_t get_fw_core_dump_size(struct kbase_device *kbdev) +{ + static char buffer[MAX_FW_CORE_DUMP_HEADER_SIZE]; + size_t size; + struct fw_core_dump_data private = {.kbdev = kbdev}; + struct seq_file m = {.private = &private, .buf = buffer, .size = MAX_FW_CORE_DUMP_HEADER_SIZE}; + struct kbase_csf_firmware_interface *interface; + + fw_core_dump_write_elf_header(&m); + if (unlikely(m.count >= m.size)) { + dev_warn(kbdev->dev, "firmware core dump header may be larger than buffer size"); + return -1; + } + size = m.count; + + list_for_each_entry(interface, &kbdev->csf.firmware_interfaces, node) { + /* Skip memory sections that cannot be read or are protected. */ + if ((interface->flags & CSF_FIRMWARE_ENTRY_PROTECTED) || + (interface->flags & CSF_FIRMWARE_ENTRY_READ) == 0) + continue; + + size += interface->num_pages * FW_PAGE_SIZE; + } + + return size; +} + /** * fw_core_dump_create - Requests firmware to save state for a firmware core dump * @kbdev: Instance of a GPU platform device that implements a CSF interface. * * Return: 0 on success, error code otherwise. */ -static int fw_core_dump_create(struct kbase_device *kbdev) +int fw_core_dump_create(struct kbase_device *kbdev) { int err; |