.. | .. |
---|
72 | 72 | static void __iomem *md_elf_mem; |
---|
73 | 73 | static resource_size_t md_elf_size; |
---|
74 | 74 | static struct proc_dir_entry *proc_rk_minidump; |
---|
| 75 | +static bool md_is_ddr_address_default(u64 phys_addr); |
---|
| 76 | +bool (*md_is_ddr_address)(u64 virt_addr) = md_is_ddr_address_default; |
---|
75 | 77 | |
---|
76 | 78 | /* Number of pending entries to be added in ToC regions */ |
---|
77 | 79 | static unsigned int pendings; |
---|
.. | .. |
---|
168 | 170 | shdr->sh_flags = SHF_WRITE; |
---|
169 | 171 | shdr->sh_offset = minidump_elfheader.elf_offset; |
---|
170 | 172 | shdr->sh_entsize = 0; |
---|
| 173 | + shdr->sh_addralign = shdr->sh_addr; /* backup */ |
---|
| 174 | + shdr->sh_entsize = entry->phys_addr; /* backup */ |
---|
171 | 175 | |
---|
172 | 176 | if (strstr((const char *)mdr->name, "note")) |
---|
173 | 177 | phdr->p_type = PT_NOTE; |
---|
.. | .. |
---|
178 | 182 | phdr->p_paddr = entry->phys_addr; |
---|
179 | 183 | phdr->p_filesz = phdr->p_memsz = mdr->region_size; |
---|
180 | 184 | phdr->p_flags = PF_R | PF_W; |
---|
| 185 | + phdr->p_align = phdr->p_paddr; /* backup */ |
---|
181 | 186 | minidump_elfheader.elf_offset += shdr->sh_size; |
---|
182 | 187 | mdr->md_valid = MD_REGION_VALID; |
---|
183 | 188 | minidump_table.md_ss_toc->ss_region_count++; |
---|
.. | .. |
---|
210 | 215 | } |
---|
211 | 216 | |
---|
212 | 217 | return 0; |
---|
| 218 | +} |
---|
| 219 | + |
---|
| 220 | +int md_is_in_the_region(u64 addr) |
---|
| 221 | +{ |
---|
| 222 | + struct md_region *mdr; |
---|
| 223 | + u32 entries; |
---|
| 224 | + int i; |
---|
| 225 | + |
---|
| 226 | + entries = minidump_table.num_regions; |
---|
| 227 | + |
---|
| 228 | + for (i = 0; i < entries; i++) { |
---|
| 229 | + mdr = &minidump_table.entry[i]; |
---|
| 230 | + if (mdr->virt_addr <= addr && addr < (mdr->virt_addr + mdr->size)) |
---|
| 231 | + break; |
---|
| 232 | + } |
---|
| 233 | + |
---|
| 234 | + if (i < entries) |
---|
| 235 | + return 1; |
---|
| 236 | + else |
---|
| 237 | + return 0; |
---|
213 | 238 | } |
---|
214 | 239 | |
---|
215 | 240 | int rk_minidump_update_region(int regno, const struct md_region *entry) |
---|
.. | .. |
---|
254 | 279 | phdr = elf_program(hdr, regno + 1); |
---|
255 | 280 | |
---|
256 | 281 | shdr->sh_addr = (elf_addr_t)entry->virt_addr; |
---|
| 282 | + shdr->sh_addralign = shdr->sh_addr; /* backup */ |
---|
| 283 | + shdr->sh_entsize = entry->phys_addr; /* backup */ |
---|
257 | 284 | phdr->p_vaddr = entry->virt_addr; |
---|
258 | 285 | phdr->p_paddr = entry->phys_addr; |
---|
| 286 | + phdr->p_align = phdr->p_paddr; /* backup */ |
---|
259 | 287 | |
---|
260 | 288 | err_unlock: |
---|
261 | 289 | read_unlock_irqrestore(&mdt_remove_lock, flags); |
---|
.. | .. |
---|
595 | 623 | .proc_read = rk_minidump_read_elf, |
---|
596 | 624 | }; |
---|
597 | 625 | |
---|
| 626 | +static bool md_is_ddr_address_rk3588(u64 phys_addr) |
---|
| 627 | +{ |
---|
| 628 | + /* peripheral address space */ |
---|
| 629 | + if (phys_addr >= 0xf0000000 && phys_addr < 0x100000000) |
---|
| 630 | + return false; |
---|
| 631 | + /* DDR is up to 32GB */ |
---|
| 632 | + if (phys_addr > 0x800000000) |
---|
| 633 | + return false; |
---|
| 634 | + return true; |
---|
| 635 | +} |
---|
| 636 | + |
---|
| 637 | +static bool md_is_ddr_address_default(u64 phys_addr) |
---|
| 638 | +{ |
---|
| 639 | + return true; |
---|
| 640 | +} |
---|
| 641 | + |
---|
598 | 642 | static int rk_minidump_driver_probe(struct platform_device *pdev) |
---|
599 | 643 | { |
---|
600 | 644 | unsigned int i; |
---|
.. | .. |
---|
655 | 699 | phdr = (Elf64_Phdr *)(md_elf_mem + (ulong)ehdr->e_phoff); |
---|
656 | 700 | phdr += ehdr->e_phnum - 1; |
---|
657 | 701 | md_elf_size = phdr->p_memsz + phdr->p_offset; |
---|
658 | | - |
---|
659 | | - pr_info("Create /proc/rk_md/minidump...\n"); |
---|
| 702 | + if (md_elf_size > r_size) |
---|
| 703 | + md_elf_size = r_size; |
---|
| 704 | + pr_info("Create /proc/rk_md/minidump, size:0x%llx...\n", md_elf_size); |
---|
660 | 705 | proc_rk_minidump = proc_create("minidump", 0400, base_dir, &rk_minidump_proc_ops); |
---|
| 706 | + } else { |
---|
| 707 | + pr_info("Create /proc/rk_md/minidump fail...\n"); |
---|
661 | 708 | } |
---|
662 | 709 | |
---|
| 710 | + if (of_machine_is_compatible("rockchip,rk3588")) |
---|
| 711 | + md_is_ddr_address = md_is_ddr_address_rk3588; |
---|
| 712 | + |
---|
663 | 713 | /* Check global minidump support initialization */ |
---|
664 | 714 | if (!md_global_toc->md_toc_init) { |
---|
665 | 715 | pr_err("System Minidump TOC not initialized\n"); |
---|