| .. | .. |
|---|
| 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"); |
|---|