xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_firmware_core_dump.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3  *
4  * (C) COPYRIGHT 2021-2022 ARM Limited. All rights reserved.
5  *
6  * This program is free software and is provided to you under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation, and any use by you of this program is subject to the terms
9  * of such GNU license.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you can access it online at
18  * http://www.gnu.org/licenses/gpl-2.0.html.
19  *
20  */
21 
22 #include <linux/kernel.h>
23 #include <linux/device.h>
24 #include <linux/list.h>
25 #include <linux/file.h>
26 #include <linux/elf.h>
27 #include <linux/elfcore.h>
28 
29 #include "mali_kbase.h"
30 #include "mali_kbase_csf_firmware_core_dump.h"
31 #include "backend/gpu/mali_kbase_pm_internal.h"
32 
33 /* Page size in bytes in use by MCU. */
34 #define FW_PAGE_SIZE 4096
35 
36 /*
37  * FW image header core dump data format supported.
38  * Currently only version 0.1 is supported.
39  */
40 #define FW_CORE_DUMP_DATA_VERSION_MAJOR 0
41 #define FW_CORE_DUMP_DATA_VERSION_MINOR 1
42 
43 /* Full version of the image header core dump data format */
44 #define FW_CORE_DUMP_DATA_VERSION                                                                  \
45 	((FW_CORE_DUMP_DATA_VERSION_MAJOR << 8) | FW_CORE_DUMP_DATA_VERSION_MINOR)
46 
47 /* Validity flag to indicate if the MCU registers in the buffer are valid */
48 #define FW_MCU_STATUS_MASK 0x1
49 #define FW_MCU_STATUS_VALID (1 << 0)
50 
51 /* Core dump entry fields */
52 #define FW_CORE_DUMP_VERSION_INDEX 0
53 #define FW_CORE_DUMP_START_ADDR_INDEX 1
54 
55 /* MCU registers stored by a firmware core dump */
56 struct fw_core_dump_mcu {
57 	u32 r0;
58 	u32 r1;
59 	u32 r2;
60 	u32 r3;
61 	u32 r4;
62 	u32 r5;
63 	u32 r6;
64 	u32 r7;
65 	u32 r8;
66 	u32 r9;
67 	u32 r10;
68 	u32 r11;
69 	u32 r12;
70 	u32 sp;
71 	u32 lr;
72 	u32 pc;
73 };
74 
75 /* Any ELF definitions used in this file are from elf.h/elfcore.h except
76  * when specific 32-bit versions are required (mainly for the
77  * ELF_PRSTATUS32 note that is used to contain the MCU registers).
78  */
79 
80 /* - 32-bit version of timeval structures used in ELF32 PRSTATUS note. */
81 struct prstatus32_timeval {
82 	int tv_sec;
83 	int tv_usec;
84 };
85 
86 /* - Structure defining ELF32 PRSTATUS note contents, as defined by the
87  *   GNU binutils BFD library used by GDB, in bfd/hosts/x86-64linux.h.
88  *   Note: GDB checks for the size of this structure to be 0x94.
89  *   Modified pr_reg (array containing the Arm 32-bit MCU registers) to
90  *   use u32[18] instead of elf_gregset32_t to prevent introducing new typedefs.
91  */
92 struct elf_prstatus32 {
93 	struct elf_siginfo pr_info;		/* Info associated with signal. */
94 	short int pr_cursig;			/* Current signal. */
95 	unsigned int pr_sigpend;		/* Set of pending signals. */
96 	unsigned int pr_sighold;		/* Set of held signals. */
97 	pid_t pr_pid;
98 	pid_t pr_ppid;
99 	pid_t pr_pgrp;
100 	pid_t pr_sid;
101 	struct prstatus32_timeval pr_utime;	/* User time. */
102 	struct prstatus32_timeval pr_stime;	/* System time. */
103 	struct prstatus32_timeval pr_cutime;	/* Cumulative user time. */
104 	struct prstatus32_timeval pr_cstime;	/* Cumulative system time. */
105 	u32 pr_reg[18];				/* GP registers. */
106 	int pr_fpvalid;				/* True if math copro being used. */
107 };
108 
109 /**
110  * struct fw_core_dump_data - Context for seq_file operations used on 'fw_core_dump'
111  * debugfs file.
112  * @kbdev: Instance of a GPU platform device that implements a CSF interface.
113  */
114 struct fw_core_dump_data {
115 	struct kbase_device *kbdev;
116 };
117 
118 /*
119  * struct fw_core_dump_seq_off - Iterator for seq_file operations used on 'fw_core_dump'
120  * debugfs file.
121  * @interface: current firmware memory interface
122  * @page_num: current page number (0..) within @interface
123  */
124 struct fw_core_dump_seq_off {
125 	struct kbase_csf_firmware_interface *interface;
126 	u32 page_num;
127 };
128 
129 /**
130  * fw_get_core_dump_mcu - Get the MCU registers saved by a firmware core dump
131  *
132  * @kbdev: Instance of a GPU platform device that implements a CSF interface.
133  * @regs:  Pointer to a core dump mcu struct where the MCU registers are copied
134  *         to. Should be allocated by the called.
135  *
136  * Return: 0 if successfully copied the MCU registers, negative error code otherwise.
137  */
fw_get_core_dump_mcu(struct kbase_device * kbdev,struct fw_core_dump_mcu * regs)138 static int fw_get_core_dump_mcu(struct kbase_device *kbdev, struct fw_core_dump_mcu *regs)
139 {
140 	unsigned int i;
141 	u32 status = 0;
142 	u32 data_addr = kbdev->csf.fw_core_dump.mcu_regs_addr;
143 	u32 *data = (u32 *)regs;
144 
145 	/* Check if the core dump entry exposed the buffer */
146 	if (!regs || !kbdev->csf.fw_core_dump.available)
147 		return -EPERM;
148 
149 	/* Check if the data in the buffer is valid, if not, return error */
150 	kbase_csf_read_firmware_memory(kbdev, data_addr, &status);
151 	if ((status & FW_MCU_STATUS_MASK) != FW_MCU_STATUS_VALID)
152 		return -EPERM;
153 
154 	/* According to image header documentation, the MCU registers core dump
155 	 * buffer is 32-bit aligned.
156 	 */
157 	for (i = 1; i <= sizeof(struct fw_core_dump_mcu) / sizeof(u32); ++i)
158 		kbase_csf_read_firmware_memory(kbdev, data_addr + i * sizeof(u32), &data[i - 1]);
159 
160 	return 0;
161 }
162 
163 /**
164  * fw_core_dump_fill_elf_header - Initializes an ELF32 header
165  * @hdr:	ELF32 header to initialize
166  * @sections:	Number of entries in the ELF program header table
167  *
168  * Initializes an ELF32 header for an ARM 32-bit little-endian
169  * 'Core file' object file.
170  */
fw_core_dump_fill_elf_header(struct elf32_hdr * hdr,unsigned int sections)171 static void fw_core_dump_fill_elf_header(struct elf32_hdr *hdr, unsigned int sections)
172 {
173 	/* Reset all members in header. */
174 	memset(hdr, 0, sizeof(*hdr));
175 
176 	/* Magic number identifying file as an ELF object. */
177 	memcpy(hdr->e_ident, ELFMAG, SELFMAG);
178 
179 	/* Identify file as 32-bit, little-endian, using current
180 	 * ELF header version, with no OS or ABI specific ELF
181 	 * extensions used.
182 	 */
183 	hdr->e_ident[EI_CLASS] = ELFCLASS32;
184 	hdr->e_ident[EI_DATA] = ELFDATA2LSB;
185 	hdr->e_ident[EI_VERSION] = EV_CURRENT;
186 	hdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
187 
188 	/* 'Core file' type of object file. */
189 	hdr->e_type = ET_CORE;
190 
191 	/* ARM 32-bit architecture (AARCH32) */
192 	hdr->e_machine = EM_ARM;
193 
194 	/* Object file version: the original format. */
195 	hdr->e_version = EV_CURRENT;
196 
197 	/* Offset of program header table in file. */
198 	hdr->e_phoff = sizeof(struct elf32_hdr);
199 
200 	/* No processor specific flags. */
201 	hdr->e_flags = 0;
202 
203 	/* Size of the ELF header in bytes. */
204 	hdr->e_ehsize = sizeof(struct elf32_hdr);
205 
206 	/* Size of the ELF program header entry in bytes. */
207 	hdr->e_phentsize = sizeof(struct elf32_phdr);
208 
209 	/* Number of entries in the program header table. */
210 	hdr->e_phnum = sections;
211 }
212 
213 /**
214  * fw_core_dump_fill_elf_program_header_note - Initializes an ELF32 program header
215  * for holding auxiliary information
216  * @phdr:		ELF32 program header
217  * @file_offset:	Location of the note in the file in bytes
218  * @size:		Size of the note in bytes.
219  *
220  * Initializes an ELF32 program header describing auxiliary information (containing
221  * one or more notes) of @size bytes alltogether located in the file at offset
222  * @file_offset.
223  */
fw_core_dump_fill_elf_program_header_note(struct elf32_phdr * phdr,u32 file_offset,u32 size)224 static void fw_core_dump_fill_elf_program_header_note(struct elf32_phdr *phdr, u32 file_offset,
225 						      u32 size)
226 {
227 	/* Auxiliary information (note) in program header. */
228 	phdr->p_type = PT_NOTE;
229 
230 	/* Location of first note in file in bytes. */
231 	phdr->p_offset = file_offset;
232 
233 	/* Size of all notes combined in bytes. */
234 	phdr->p_filesz = size;
235 
236 	/* Other members not relevant for a note. */
237 	phdr->p_vaddr = 0;
238 	phdr->p_paddr = 0;
239 	phdr->p_memsz = 0;
240 	phdr->p_align = 0;
241 	phdr->p_flags = 0;
242 }
243 
244 /**
245  * fw_core_dump_fill_elf_program_header - Initializes an ELF32 program header for a loadable segment
246  * @phdr:		ELF32 program header to initialize.
247  * @file_offset:	Location of loadable segment in file in bytes
248  *                      (aligned to FW_PAGE_SIZE bytes)
249  * @vaddr:		32-bit virtual address where to write the segment
250  *                      (aligned to FW_PAGE_SIZE bytes)
251  * @size:		Size of the segment in bytes.
252  * @flags:		CSF_FIRMWARE_ENTRY_* flags describing access permissions.
253  *
254  * Initializes an ELF32 program header describing a loadable segment of
255  * @size bytes located in the file at offset @file_offset to be loaded
256  * at virtual address @vaddr with access permissions as described by
257  * CSF_FIRMWARE_ENTRY_* flags in @flags.
258  */
fw_core_dump_fill_elf_program_header(struct elf32_phdr * phdr,u32 file_offset,u32 vaddr,u32 size,u32 flags)259 static void fw_core_dump_fill_elf_program_header(struct elf32_phdr *phdr, u32 file_offset,
260 						 u32 vaddr, u32 size, u32 flags)
261 {
262 	/* Loadable segment in program header. */
263 	phdr->p_type = PT_LOAD;
264 
265 	/* Location of segment in file in bytes. Aligned to p_align bytes. */
266 	phdr->p_offset = file_offset;
267 
268 	/* Virtual address of segment. Aligned to p_align bytes. */
269 	phdr->p_vaddr = vaddr;
270 
271 	/* Physical address of segment. Not relevant. */
272 	phdr->p_paddr = 0;
273 
274 	/* Size of segment in file and memory. */
275 	phdr->p_filesz = size;
276 	phdr->p_memsz = size;
277 
278 	/* Alignment of segment in the file and memory in bytes (integral power of 2). */
279 	phdr->p_align = FW_PAGE_SIZE;
280 
281 	/* Set segment access permissions. */
282 	phdr->p_flags = 0;
283 	if (flags & CSF_FIRMWARE_ENTRY_READ)
284 		phdr->p_flags |= PF_R;
285 	if (flags & CSF_FIRMWARE_ENTRY_WRITE)
286 		phdr->p_flags |= PF_W;
287 	if (flags & CSF_FIRMWARE_ENTRY_EXECUTE)
288 		phdr->p_flags |= PF_X;
289 }
290 
291 /**
292  * fw_core_dump_get_prstatus_note_size - Calculates size of a ELF32 PRSTATUS note
293  * @name:	Name given to the PRSTATUS note.
294  *
295  * Calculates the size of a 32-bit PRSTATUS note (which contains information
296  * about a process like the current MCU registers) taking into account
297  * @name must be padded to a 4-byte multiple.
298  *
299  * Return: size of 32-bit PRSTATUS note in bytes.
300  */
fw_core_dump_get_prstatus_note_size(char * name)301 static unsigned int fw_core_dump_get_prstatus_note_size(char *name)
302 {
303 	return sizeof(struct elf32_note) + roundup(strlen(name) + 1, 4) +
304 	       sizeof(struct elf_prstatus32);
305 }
306 
307 /**
308  * fw_core_dump_fill_elf_prstatus - Initializes an ELF32 PRSTATUS structure
309  * @prs:	ELF32 PRSTATUS note to initialize
310  * @regs:	MCU registers to copy into the PRSTATUS note
311  *
312  * Initializes an ELF32 PRSTATUS structure with MCU registers @regs.
313  * Other process information is N/A for CSF Firmware.
314  */
fw_core_dump_fill_elf_prstatus(struct elf_prstatus32 * prs,struct fw_core_dump_mcu * regs)315 static void fw_core_dump_fill_elf_prstatus(struct elf_prstatus32 *prs,
316 					   struct fw_core_dump_mcu *regs)
317 {
318 	/* Only fill in registers (32-bit) of PRSTATUS note. */
319 	memset(prs, 0, sizeof(*prs));
320 	prs->pr_reg[0] = regs->r0;
321 	prs->pr_reg[1] = regs->r1;
322 	prs->pr_reg[2] = regs->r2;
323 	prs->pr_reg[3] = regs->r3;
324 	prs->pr_reg[4] = regs->r4;
325 	prs->pr_reg[5] = regs->r5;
326 	prs->pr_reg[6] = regs->r0;
327 	prs->pr_reg[7] = regs->r7;
328 	prs->pr_reg[8] = regs->r8;
329 	prs->pr_reg[9] = regs->r9;
330 	prs->pr_reg[10] = regs->r10;
331 	prs->pr_reg[11] = regs->r11;
332 	prs->pr_reg[12] = regs->r12;
333 	prs->pr_reg[13] = regs->sp;
334 	prs->pr_reg[14] = regs->lr;
335 	prs->pr_reg[15] = regs->pc;
336 }
337 
338 /**
339  * fw_core_dump_create_prstatus_note - Creates an ELF32 PRSTATUS note
340  * @name:	Name for the PRSTATUS note
341  * @prs:	ELF32 PRSTATUS structure to put in the PRSTATUS note
342  * @created_prstatus_note:
343  *		Pointer to the allocated ELF32 PRSTATUS note
344  *
345  * Creates an ELF32 note with one PRSTATUS entry containing the
346  * ELF32 PRSTATUS structure @prs. Caller needs to free the created note in
347  * @created_prstatus_note.
348  *
349  * Return: 0 on failure, otherwise size of ELF32 PRSTATUS note in bytes.
350  */
fw_core_dump_create_prstatus_note(char * name,struct elf_prstatus32 * prs,struct elf32_note ** created_prstatus_note)351 static unsigned int fw_core_dump_create_prstatus_note(char *name, struct elf_prstatus32 *prs,
352 						      struct elf32_note **created_prstatus_note)
353 {
354 	struct elf32_note *note;
355 	unsigned int note_name_sz;
356 	unsigned int note_sz;
357 
358 	/* Allocate memory for ELF32 note containing a PRSTATUS note. */
359 	note_name_sz = strlen(name) + 1;
360 	note_sz = sizeof(struct elf32_note) + roundup(note_name_sz, 4) +
361 		  sizeof(struct elf_prstatus32);
362 	note = kmalloc(note_sz, GFP_KERNEL);
363 	if (!note)
364 		return 0;
365 
366 	/* Fill in ELF32 note with one entry for a PRSTATUS note. */
367 	note->n_namesz = note_name_sz;
368 	note->n_descsz = sizeof(struct elf_prstatus32);
369 	note->n_type = NT_PRSTATUS;
370 	memcpy(note + 1, name, note_name_sz);
371 	memcpy((char *)(note + 1) + roundup(note_name_sz, 4), prs, sizeof(*prs));
372 
373 	/* Return pointer and size of the created ELF32 note. */
374 	*created_prstatus_note = note;
375 	return note_sz;
376 }
377 
378 /**
379  * fw_core_dump_write_elf_header - Writes ELF header for the FW core dump
380  * @m: the seq_file handle
381  *
382  * Writes the ELF header of the core dump including program headers for
383  * memory sections and a note containing the current MCU register
384  * values.
385  *
386  * Excludes memory sections without read access permissions or
387  * are for protected memory.
388  *
389  * The data written is as follows:
390  * - ELF header
391  * - ELF PHDRs for memory sections
392  * - ELF PHDR for program header NOTE
393  * - ELF PRSTATUS note
394  * - 0-bytes padding to multiple of ELF_EXEC_PAGESIZE
395  *
396  * The actual memory section dumps should follow this (not written
397  * by this function).
398  *
399  * Retrieves the necessary information via the struct
400  * fw_core_dump_data stored in the private member of the seq_file
401  * handle.
402  *
403  * Return:
404  * * 0		- success
405  * * -ENOMEM	- not enough memory for allocating ELF32 note
406  */
fw_core_dump_write_elf_header(struct seq_file * m)407 static int fw_core_dump_write_elf_header(struct seq_file *m)
408 {
409 	struct elf32_hdr hdr;
410 	struct elf32_phdr phdr;
411 	struct fw_core_dump_data *dump_data = m->private;
412 	struct kbase_device *const kbdev = dump_data->kbdev;
413 	struct kbase_csf_firmware_interface *interface;
414 	struct elf_prstatus32 elf_prs;
415 	struct elf32_note *elf_prstatus_note;
416 	unsigned int sections = 0;
417 	unsigned int elf_prstatus_note_size;
418 	u32 elf_prstatus_offset;
419 	u32 elf_phdr_note_offset;
420 	u32 elf_memory_sections_data_offset;
421 	u32 total_pages = 0;
422 	u32 padding_size, *padding;
423 	struct fw_core_dump_mcu regs = { 0 };
424 
425 	/* Count number of memory sections. */
426 	list_for_each_entry(interface, &kbdev->csf.firmware_interfaces, node) {
427 		/* Skip memory sections that cannot be read or are protected. */
428 		if ((interface->flags & CSF_FIRMWARE_ENTRY_PROTECTED) ||
429 		    (interface->flags & CSF_FIRMWARE_ENTRY_READ) == 0)
430 			continue;
431 		sections++;
432 	}
433 
434 	/* Prepare ELF header. */
435 	fw_core_dump_fill_elf_header(&hdr, sections + 1);
436 	seq_write(m, &hdr, sizeof(struct elf32_hdr));
437 
438 	elf_prstatus_note_size = fw_core_dump_get_prstatus_note_size("CORE");
439 	/* PHDRs of PT_LOAD type. */
440 	elf_phdr_note_offset = sizeof(struct elf32_hdr) + sections * sizeof(struct elf32_phdr);
441 	/* PHDR of PT_NOTE type. */
442 	elf_prstatus_offset = elf_phdr_note_offset + sizeof(struct elf32_phdr);
443 	elf_memory_sections_data_offset = elf_prstatus_offset + elf_prstatus_note_size;
444 
445 	/* Calculate padding size to page offset. */
446 	padding_size = roundup(elf_memory_sections_data_offset, ELF_EXEC_PAGESIZE) -
447 		       elf_memory_sections_data_offset;
448 	elf_memory_sections_data_offset += padding_size;
449 
450 	/* Prepare ELF program header table. */
451 	list_for_each_entry(interface, &kbdev->csf.firmware_interfaces, node) {
452 		/* Skip memory sections that cannot be read or are protected. */
453 		if ((interface->flags & CSF_FIRMWARE_ENTRY_PROTECTED) ||
454 		    (interface->flags & CSF_FIRMWARE_ENTRY_READ) == 0)
455 			continue;
456 
457 		fw_core_dump_fill_elf_program_header(&phdr, elf_memory_sections_data_offset,
458 						     interface->virtual,
459 						     interface->num_pages * FW_PAGE_SIZE,
460 						     interface->flags);
461 
462 		seq_write(m, &phdr, sizeof(struct elf32_phdr));
463 
464 		elf_memory_sections_data_offset += interface->num_pages * FW_PAGE_SIZE;
465 		total_pages += interface->num_pages;
466 	}
467 
468 	/* Prepare PHDR of PT_NOTE type. */
469 	fw_core_dump_fill_elf_program_header_note(&phdr, elf_prstatus_offset,
470 						  elf_prstatus_note_size);
471 	seq_write(m, &phdr, sizeof(struct elf32_phdr));
472 
473 	/* Prepare ELF note of PRSTATUS type. */
474 	if (fw_get_core_dump_mcu(kbdev, &regs))
475 		dev_dbg(kbdev->dev, "MCU Registers not available, all registers set to zero");
476 	/* Even if MCU Registers are not available the ELF prstatus is still
477 	 * filled with the registers equal to zero.
478 	 */
479 	fw_core_dump_fill_elf_prstatus(&elf_prs, &regs);
480 	elf_prstatus_note_size =
481 		fw_core_dump_create_prstatus_note("CORE", &elf_prs, &elf_prstatus_note);
482 	if (elf_prstatus_note_size == 0)
483 		return -ENOMEM;
484 
485 	seq_write(m, elf_prstatus_note, elf_prstatus_note_size);
486 	kfree(elf_prstatus_note);
487 
488 	/* Pad file to page size. */
489 	padding = kzalloc(padding_size, GFP_KERNEL);
490 	seq_write(m, padding, padding_size);
491 	kfree(padding);
492 
493 	return 0;
494 }
495 
496 /**
497  * fw_core_dump_create - Requests firmware to save state for a firmware core dump
498  * @kbdev: Instance of a GPU platform device that implements a CSF interface.
499  *
500  * Return: 0 on success, error code otherwise.
501  */
fw_core_dump_create(struct kbase_device * kbdev)502 static int fw_core_dump_create(struct kbase_device *kbdev)
503 {
504 	int err;
505 
506 	/* Ensure MCU is active before requesting the core dump. */
507 	kbase_csf_scheduler_pm_active(kbdev);
508 	err = kbase_csf_scheduler_wait_mcu_active(kbdev);
509 	if (!err)
510 		err = kbase_csf_firmware_req_core_dump(kbdev);
511 
512 	kbase_csf_scheduler_pm_idle(kbdev);
513 
514 	return err;
515 }
516 
517 /**
518  * fw_core_dump_seq_start - seq_file start operation for firmware core dump file
519  * @m: the seq_file handle
520  * @_pos: holds the current position in pages
521  *        (0 or most recent position used in previous session)
522  *
523  * Starts a seq_file session, positioning the iterator for the session to page @_pos - 1
524  * within the firmware interface memory sections. @_pos value 0 is used to indicate the
525  * position of the ELF header at the start of the file.
526  *
527  * Retrieves the necessary information via the struct fw_core_dump_data stored in
528  * the private member of the seq_file handle.
529  *
530  * Return:
531  * * iterator pointer	- pointer to iterator struct fw_core_dump_seq_off
532  * * SEQ_START_TOKEN	- special iterator pointer indicating its is the start of the file
533  * * NULL		- iterator could not be allocated
534  */
fw_core_dump_seq_start(struct seq_file * m,loff_t * _pos)535 static void *fw_core_dump_seq_start(struct seq_file *m, loff_t *_pos)
536 {
537 	struct fw_core_dump_data *dump_data = m->private;
538 	struct fw_core_dump_seq_off *data;
539 	struct kbase_csf_firmware_interface *interface;
540 	loff_t pos = *_pos;
541 
542 	if (pos == 0)
543 		return SEQ_START_TOKEN;
544 
545 	/* Move iterator in the right position based on page number within
546 	 * available pages of firmware interface memory sections.
547 	 */
548 	pos--; /* ignore start token */
549 	list_for_each_entry(interface, &dump_data->kbdev->csf.firmware_interfaces, node) {
550 		/* Skip memory sections that cannot be read or are protected. */
551 		if ((interface->flags & CSF_FIRMWARE_ENTRY_PROTECTED) ||
552 		    (interface->flags & CSF_FIRMWARE_ENTRY_READ) == 0)
553 			continue;
554 
555 		if (pos >= interface->num_pages) {
556 			pos -= interface->num_pages;
557 		} else {
558 			data = kmalloc(sizeof(*data), GFP_KERNEL);
559 			if (!data)
560 				return NULL;
561 			data->interface = interface;
562 			data->page_num = pos;
563 			return data;
564 		}
565 	}
566 
567 	return NULL;
568 }
569 
570 /**
571  * fw_core_dump_seq_stop - seq_file stop operation for firmware core dump file
572  * @m: the seq_file handle
573  * @v: the current iterator (pointer to struct fw_core_dump_seq_off)
574  *
575  * Closes the current session and frees any memory related.
576  */
fw_core_dump_seq_stop(struct seq_file * m,void * v)577 static void fw_core_dump_seq_stop(struct seq_file *m, void *v)
578 {
579 	kfree(v);
580 }
581 
582 /**
583  * fw_core_dump_seq_next - seq_file next operation for firmware core dump file
584  * @m: the seq_file handle
585  * @v: the current iterator (pointer to struct fw_core_dump_seq_off)
586  * @pos: holds the current position in pages
587  *        (0 or most recent position used in previous session)
588  *
589  * Moves the iterator @v forward to the next page within the firmware interface
590  * memory sections and returns the updated position in @pos.
591  * @v value SEQ_START_TOKEN indicates the ELF header position.
592  *
593  * Return:
594  * * iterator pointer	- pointer to iterator struct fw_core_dump_seq_off
595  * * NULL		- iterator could not be allocated
596  */
fw_core_dump_seq_next(struct seq_file * m,void * v,loff_t * pos)597 static void *fw_core_dump_seq_next(struct seq_file *m, void *v, loff_t *pos)
598 {
599 	struct fw_core_dump_data *dump_data = m->private;
600 	struct fw_core_dump_seq_off *data = v;
601 	struct kbase_csf_firmware_interface *interface;
602 	struct list_head *interfaces = &dump_data->kbdev->csf.firmware_interfaces;
603 
604 	/* Is current position at the ELF header ? */
605 	if (v == SEQ_START_TOKEN) {
606 		if (list_empty(interfaces))
607 			return NULL;
608 
609 		/* Prepare iterator for starting at first page in firmware interface
610 		 * memory sections.
611 		 */
612 		data = kmalloc(sizeof(*data), GFP_KERNEL);
613 		if (!data)
614 			return NULL;
615 		data->interface =
616 			list_first_entry(interfaces, struct kbase_csf_firmware_interface, node);
617 		data->page_num = 0;
618 		++*pos;
619 		return data;
620 	}
621 
622 	/* First attempt to satisfy from current firmware interface memory section. */
623 	interface = data->interface;
624 	if (data->page_num + 1 < interface->num_pages) {
625 		data->page_num++;
626 		++*pos;
627 		return data;
628 	}
629 
630 	/* Need next firmware interface memory section. This could be the last one. */
631 	if (list_is_last(&interface->node, interfaces)) {
632 		kfree(data);
633 		return NULL;
634 	}
635 
636 	/* Move to first page in next firmware interface memory section. */
637 	data->interface = list_next_entry(interface, node);
638 	data->page_num = 0;
639 	++*pos;
640 
641 	return data;
642 }
643 
644 /**
645  * fw_core_dump_seq_show - seq_file show operation for firmware core dump file
646  * @m: the seq_file handle
647  * @v: the current iterator (pointer to struct fw_core_dump_seq_off)
648  *
649  * Writes the current page in a firmware interface memory section indicated
650  * by the iterator @v to the file. If @v is SEQ_START_TOKEN the ELF
651  * header is written.
652  *
653  * Return: 0 on success, error code otherwise.
654  */
fw_core_dump_seq_show(struct seq_file * m,void * v)655 static int fw_core_dump_seq_show(struct seq_file *m, void *v)
656 {
657 	struct fw_core_dump_seq_off *data = v;
658 	struct page *page;
659 	u32 *p;
660 
661 	/* Either write the ELF header or current page. */
662 	if (v == SEQ_START_TOKEN)
663 		return fw_core_dump_write_elf_header(m);
664 
665 	/* Write the current page. */
666 	page = as_page(data->interface->phys[data->page_num]);
667 	p = kmap_atomic(page);
668 	seq_write(m, p, FW_PAGE_SIZE);
669 	kunmap_atomic(p);
670 
671 	return 0;
672 }
673 
674 /* Sequence file operations for firmware core dump file. */
675 static const struct seq_operations fw_core_dump_seq_ops = {
676 	.start = fw_core_dump_seq_start,
677 	.next = fw_core_dump_seq_next,
678 	.stop = fw_core_dump_seq_stop,
679 	.show = fw_core_dump_seq_show,
680 };
681 
682 /**
683  * fw_core_dump_debugfs_open - callback for opening the 'fw_core_dump' debugfs file
684  * @inode: inode of the file
685  * @file:  file pointer
686  *
687  * Prepares for servicing a write request to request a core dump from firmware and
688  * a read request to retrieve the core dump.
689  *
690  * Returns an error if the firmware is not initialized yet.
691  *
692  * Return: 0 on success, error code otherwise.
693  */
fw_core_dump_debugfs_open(struct inode * inode,struct file * file)694 static int fw_core_dump_debugfs_open(struct inode *inode, struct file *file)
695 {
696 	struct kbase_device *const kbdev = inode->i_private;
697 	struct fw_core_dump_data *dump_data;
698 	int ret;
699 
700 	/* Fail if firmware is not initialized yet. */
701 	if (!kbdev->csf.firmware_inited) {
702 		ret = -ENODEV;
703 		goto open_fail;
704 	}
705 
706 	/* Open a sequence file for iterating through the pages in the
707 	 * firmware interface memory pages. seq_open stores a
708 	 * struct seq_file * in the private_data field of @file.
709 	 */
710 	ret = seq_open(file, &fw_core_dump_seq_ops);
711 	if (ret)
712 		goto open_fail;
713 
714 	/* Allocate a context for sequence file operations. */
715 	dump_data = kmalloc(sizeof(*dump_data), GFP_KERNEL);
716 	if (!dump_data) {
717 		ret = -ENOMEM;
718 		goto out;
719 	}
720 
721 	/* Kbase device will be shared with sequence file operations. */
722 	dump_data->kbdev = kbdev;
723 
724 	/* Link our sequence file context. */
725 	((struct seq_file *)file->private_data)->private = dump_data;
726 
727 	return 0;
728 out:
729 	seq_release(inode, file);
730 open_fail:
731 	return ret;
732 }
733 
734 /**
735  * fw_core_dump_debugfs_write - callback for a write to the 'fw_core_dump' debugfs file
736  * @file:  file pointer
737  * @ubuf:  user buffer containing data to store
738  * @count: number of bytes in user buffer
739  * @ppos:  file position
740  *
741  * Any data written to the file triggers a firmware core dump request which
742  * subsequently can be retrieved by reading from the file.
743  *
744  * Return: @count if the function succeeded. An error code on failure.
745  */
fw_core_dump_debugfs_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)746 static ssize_t fw_core_dump_debugfs_write(struct file *file, const char __user *ubuf, size_t count,
747 					  loff_t *ppos)
748 {
749 	int err;
750 	struct fw_core_dump_data *dump_data = ((struct seq_file *)file->private_data)->private;
751 	struct kbase_device *const kbdev = dump_data->kbdev;
752 
753 	CSTD_UNUSED(ppos);
754 
755 	err = fw_core_dump_create(kbdev);
756 
757 	return err ? err : count;
758 }
759 
760 /**
761  * fw_core_dump_debugfs_release - callback for releasing the 'fw_core_dump' debugfs file
762  * @inode: inode of the file
763  * @file:  file pointer
764  *
765  * Return: 0 on success, error code otherwise.
766  */
fw_core_dump_debugfs_release(struct inode * inode,struct file * file)767 static int fw_core_dump_debugfs_release(struct inode *inode, struct file *file)
768 {
769 	struct fw_core_dump_data *dump_data = ((struct seq_file *)file->private_data)->private;
770 
771 	seq_release(inode, file);
772 
773 	kfree(dump_data);
774 
775 	return 0;
776 }
777 /* Debugfs file operations for firmware core dump file. */
778 static const struct file_operations kbase_csf_fw_core_dump_fops = {
779 	.owner = THIS_MODULE,
780 	.open = fw_core_dump_debugfs_open,
781 	.read = seq_read,
782 	.write = fw_core_dump_debugfs_write,
783 	.llseek = seq_lseek,
784 	.release = fw_core_dump_debugfs_release,
785 };
786 
kbase_csf_firmware_core_dump_init(struct kbase_device * const kbdev)787 void kbase_csf_firmware_core_dump_init(struct kbase_device *const kbdev)
788 {
789 #if IS_ENABLED(CONFIG_DEBUG_FS)
790 	debugfs_create_file("fw_core_dump", 0600, kbdev->mali_debugfs_directory, kbdev,
791 			    &kbase_csf_fw_core_dump_fops);
792 #endif /* CONFIG_DEBUG_FS */
793 }
794 
kbase_csf_firmware_core_dump_entry_parse(struct kbase_device * kbdev,const u32 * entry)795 int kbase_csf_firmware_core_dump_entry_parse(struct kbase_device *kbdev, const u32 *entry)
796 {
797 	/* Casting to u16 as version is defined by bits 15:0 */
798 	kbdev->csf.fw_core_dump.version = (u16)entry[FW_CORE_DUMP_VERSION_INDEX];
799 
800 	if (kbdev->csf.fw_core_dump.version != FW_CORE_DUMP_DATA_VERSION)
801 		return -EPERM;
802 
803 	kbdev->csf.fw_core_dump.mcu_regs_addr = entry[FW_CORE_DUMP_START_ADDR_INDEX];
804 	kbdev->csf.fw_core_dump.available = true;
805 
806 	return 0;
807 }
808