diff -Naru ./makedumpfile-1.7.4/arch/sw_64.c ./makedumpfile-1.7.4-sw64/arch/sw_64.c --- ./makedumpfile-1.7.4/arch/sw_64.c 1970-01-01 08:00:00.000000000 +0800 +++ ./makedumpfile-1.7.4-sw64/arch/sw_64.c 2025-04-01 08:37:38.886978748 +0800 @@ -0,0 +1,328 @@ +/* + * arch/sw_64.c + * + * Copyright (C) 2021 Uniontech, Bai xin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation (version 2 of the License). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef __sw_64__ + +#include "../elf_info.h" +#include "../makedumpfile.h" +#include "../print_info.h" + +typedef struct { + unsigned long pgd; +} pgd_t; + +typedef struct { + pgd_t pgd; +} pud_t; + +typedef struct { + pud_t pud; +} pmd_t; + +typedef struct { + unsigned long pte; +} pte_t; + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pud(x) ((pud_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) + +static int pgtable_level = 4; +static int va_bits = 53; + +#define pgd_val(x) ((x).pgd) +#define pud_val(x) (pgd_val((x).pgd)) +#define pmd_val(x) (pud_val((x).pud)) +#define pte_val(x) ((x).pte) + +/* See 'include/uapi/linux/const.h' for definitions below */ +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) + +/* See 'include/asm/pgtable-types.h' for definitions below */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; + +#define PAGE_SHIFT 13 + +/* See 'arch/sw_64/include/asm/pgtable-hwdef.h' for definitions below */ + +#define SW_64_HW_PGTABLE_LEVEL_SHIFT(n) ((PAGE_SHIFT - 3) * (4 - (n)) + 3) + +#define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3)) + +/* + * PMD_SHIFT determines the size a level 2 page table entry can map. + */ +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PTRS_PER_PMD PTRS_PER_PTE + +/* + * PUD_SHIFT determines the size a level 1 page table entry can map. + */ +#define PUD_SHIFT (PAGE_SHIFT + 2 * (PAGE_SHIFT - 3)) +#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) +#define PTRS_PER_PUD PTRS_PER_PTE + +/* + * PGDIR_SHIFT determines the size a top-level page table entry can map + * (depending on the configuration, this level can be 0, 1 or 2). + */ +#define PGDIR_SHIFT (PAGE_SHIFT + 3* (PAGE_SHIFT - 3)) +#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) +#define PTRS_PER_PGD (1UL << (PAGE_SHIFT - 3)) + +#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) +#define pgd_offset(pgd, vaddr) ((pgd_t *)(pgd) + pgd_index(vaddr)) + +#define __SW_PAGE_OFFSET 0xfff0000000000000 +#define __START_KERNEL_map __SW_PAGE_OFFSET +#define __SW_MAX_PHYSMEM_BITS 48 +#define __SW_SECTION_SIZE_BITS 28 + +static unsigned long long +__pa(unsigned long x) +{ + unsigned long y = x; + + if (y >= __START_KERNEL_map) { + y -= __START_KERNEL_map; + } else { + y -= __SW_PAGE_OFFSET; + } + return y; +} + +#define _PFN_BITS 40 +#define _PTE_FLAGS_BITS (64 - _PFN_BITS) +#define _PFN_MASK 0x7FFFFFFFF000000UL +#define PAGE_OFFSET 0xfff0000000000000 +static inline unsigned long pgd_page_vaddr(pgd_t pgd) +{ + return ((pgd_val(pgd) & _PFN_MASK) >> (_PTE_FLAGS_BITS-PAGE_SHIFT)); +} +#define PTRS_PER_PAGE (1UL << (PAGE_SHIFT - 3)) +static inline unsigned long _pud_offset(unsigned long vaddr) +{ + return (vaddr >> PUD_SHIFT) & (PTRS_PER_PAGE - 1); +} +static inline pud_t *pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr) +{ + pud_t *ret = (pud_t *) pgd_page_vaddr(*pgdv) + + _pud_offset(vaddr); + return ret; +} + +static inline unsigned long pud_page_vaddr(pud_t pud) +{ + return ((pud_val(pud) & _PFN_MASK) >> (_PTE_FLAGS_BITS-PAGE_SHIFT)); +} +static inline unsigned long _pmd_offset(unsigned long vaddr) +{ + return ((vaddr >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); +} +static inline pmd_t *pmd_offset(pud_t *puda, pud_t *pudv, unsigned long vaddr) +{ + pmd_t *ret = (pmd_t *) pud_page_vaddr(*pudv) + + _pmd_offset(vaddr); + return ret; +} + +static inline unsigned long +pmd_page_vaddr(pmd_t pmd) +{ + return ((pmd_val(pmd) & _PFN_MASK) >> (_PTE_FLAGS_BITS-PAGE_SHIFT)); +} +static inline unsigned long _pte_offset(unsigned long address) +{ + return ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); +} +static inline pte_t *pte_offset(pmd_t *dir, unsigned long address) +{ + pte_t *ret = (pte_t *) pmd_page_vaddr(*dir) + + _pte_offset(address); + return ret; +} + +#define _PAGE_VALID 0x0001 +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & _PAGE_VALID; +} + +ulong +get_stext_symbol(void) +{ + int found; + FILE *fp; + char buf[BUFSIZE]; + char *kallsyms[MAXARGS]; + ulong kallsym; + + if (!file_exists("/proc/kallsyms")) { + ERRMSG("(%s) does not exist, will not be able to read symbols. %s\n", + "/proc/kallsyms", strerror(errno)); + return FALSE; + } + + if ((fp = fopen("/proc/kallsyms", "r")) == NULL) { + ERRMSG("Cannot open (%s) to read symbols. %s\n", + "/proc/kallsyms", strerror(errno)); + return FALSE; + } + + found = FALSE; + kallsym = 0; + + while (!found && fgets(buf, BUFSIZE, fp) && + (parse_line(buf, kallsyms) == 3)) { + if (hexadecimal(kallsyms[0], 0) && + STREQ(kallsyms[2], "_stext")) { + kallsym = htol(kallsyms[0], 0); + found = TRUE; + break; + } + } + fclose(fp); + + return(found ? kallsym : FALSE); +} + +int +get_machdep_info_sw_64(void) +{ + info->section_size_bits = __SW_SECTION_SIZE_BITS; + info->max_physmem_bits = __SW_MAX_PHYSMEM_BITS; + return TRUE; +} + +unsigned long long +kvtop_xen_sw_64(unsigned long kvaddr) +{ + return ERROR; +} + +int +get_xen_basic_info_sw_64(void) +{ + return ERROR; +} + +int +get_xen_info_sw_64(void) +{ + return ERROR; +} + +/* + * vaddr_to_paddr_sw_64() - translate arbitrary virtual address to physical + * @vaddr: virtual address to translate + * + * Function translates @vaddr into physical address using page tables. This + * address can be any virtual address. Returns physical address of the + * corresponding virtual address or %NOT_PADDR when there is no translation. + */ +unsigned long long +vaddr_to_paddr_sw_64(unsigned long vaddr) +{ + unsigned long long paddr = NOT_PADDR; + unsigned long long swapper_phys; + pgd_t *pgda, pgdv; + pud_t *puda, pudv; + pmd_t *pmda, pmdv; + pte_t *ptea, ptev; + + if (vaddr > 0xffffffff80000000){ + paddr = vaddr - 0xffffffff80000000; + DEBUG_MSG("direct map:%-16lx ----> %-16lx\n", vaddr, paddr); + return paddr; + } + + if (vaddr > 0xfff0000000000000 && vaddr < 0xfff0ffffffffffff){ + paddr = vaddr - 0xfff0000000000000; + DEBUG_MSG("direct map:%-16lx ----> %-16lx\n", vaddr, paddr); + return paddr; + } + + if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) { + ERRMSG("Can't get the symbol of swapper_pg_dir.\n"); + return NOT_PADDR; + } + + swapper_phys = __pa(SYMBOL(swapper_pg_dir)); + DEBUG_MSG("start look table vaddr:%-16lx\n", vaddr); + DEBUG_MSG("swapper_pg_dir:%-16lx\n", SYMBOL(swapper_pg_dir)); + + pgda = pgd_offset(swapper_phys, vaddr); + DEBUG_MSG("pgd:%-16lx offset:%-16lx pgda:%-16lx", swapper_phys, pgd_index(vaddr) * sizeof(pgd_t), pgda); + if (!readmem(PADDR, (unsigned long long)pgda, &pgdv, sizeof(pgdv))) { + ERRMSG("Can't read pgd\n"); + return NOT_PADDR; + } + DEBUG_MSG(" pgdv:%-16lx\n", pgdv); + + puda = pud_offset(pgda, &pgdv, vaddr); + DEBUG_MSG("pud:%-16lx offset:%-16lx puda:%-16lx", pgd_page_vaddr(pgdv), _pud_offset(vaddr) * sizeof(pud_t), puda); + if (!readmem(PADDR, (unsigned long long)puda, &pudv, sizeof(pudv))) { + ERRMSG("Can't read pud\n"); + return NOT_PADDR; + } + DEBUG_MSG(" pudv:%-16lx\n", pudv); + + if (!pud_val(pudv)) { + DEBUG_MSG("addr = %#lx, pgd = %#lx, pud = %#lx\n", + vaddr, pgd_val(pgdv), pud_val(pudv)); + return 0; + } + + pmda = pmd_offset(puda, &pudv, vaddr); + DEBUG_MSG("pmd:%-16lx offset:%-16lx pmda:%-16lx", pud_page_vaddr(pudv), _pmd_offset(vaddr) * sizeof(pgd_t), pmda); + if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) { + ERRMSG("Can't read pmd\n"); + return NOT_PADDR; + } + DEBUG_MSG(" pmdv:%-16lx\n", pmdv); + + ptea = pte_offset(&pmdv, vaddr); + DEBUG_MSG("pte:%-16lx offset:%-16lx ptea:%-16lx", pmd_page_vaddr(pmdv), _pte_offset(vaddr) * sizeof(pgd_t), ptea); + if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) { + ERRMSG("Can't read pte\n"); + return NOT_PADDR; + } + DEBUG_MSG(" ptev:%-16lx\n", ptev); + + if (pte_present(ptev)) { + paddr = ((pte_val(ptev) & _PFN_MASK) >> (_PTE_FLAGS_BITS-PAGE_SHIFT)) + (vaddr & ((1 << PAGE_SHIFT) - 1)); + DEBUG_MSG("paddr:%-16lx", paddr); + } + pte_val(ptev) = 0; + readmem(PADDR, (unsigned long long)paddr, &ptev, sizeof(ptev)); + DEBUG_MSG(" value:%-16lx\n", ptev); + return paddr; +} + +#endif /* __sw_64__ */ diff -Naru ./makedumpfile-1.7.4/makedumpfile.h ./makedumpfile-1.7.4-sw64/makedumpfile.h --- ./makedumpfile-1.7.4/makedumpfile.h 2025-04-01 08:34:04.990967629 +0800 +++ ./makedumpfile-1.7.4-sw64/makedumpfile.h 2025-04-01 08:37:38.886978748 +0800 @@ -829,6 +829,47 @@ #endif /* __s390x__ */ +#ifdef __sw_64__ +//#define __PAGE_OFFSET (info->page_size - 1) +#define KERNELBASE (0) +#define KVBASE KERNELBASE +//#define _SECTION_SIZE_BITS (28) +//#define _MAX_PHYSMEM_BITS_ORIG (42) +//#define _MAX_PHYSMEM_BITS_3_3 (46) +// +///* Bits in the segment/region table address-space-control-element */ +//#define _ASCE_TYPE_MASK 0x0c +//#define _ASCE_TABLE_LENGTH 0x03 /* region table length */ +// +//#define TABLE_LEVEL(x) (((x) & _ASCE_TYPE_MASK) >> 2) +//#define TABLE_LENGTH(x) ((x) & _ASCE_TABLE_LENGTH) +// +///* Bits in the region table entry */ +//#define _REGION_ENTRY_ORIGIN ~0xfffUL /* region table origin*/ +//#define _REGION_ENTRY_TYPE_MASK 0x0c /* region table type mask */ +//#define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */ +//#define _REGION_ENTRY_LENGTH 0x03 /* region table length */ +//#define _REGION_ENTRY_LARGE 0x400 +//#define _REGION_OFFSET_MASK 0x7ffUL /* region/segment table offset mask */ +// +//#define RSG_TABLE_LEVEL(x) (((x) & _REGION_ENTRY_TYPE_MASK) >> 2) +//#define RSG_TABLE_LENGTH(x) ((x) & _REGION_ENTRY_LENGTH) +// +///* Bits in the segment table entry */ +//#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL +//#define _SEGMENT_ENTRY_LARGE 0x400 +//#define _SEGMENT_ENTRY_CO 0x100 +//#define _SEGMENT_PAGE_SHIFT 31 +//#define _SEGMENT_INDEX_SHIFT 20 +// +///* Hardware bits in the page table entry */ +//#define _PAGE_ZERO 0x800 /* Bit pos 52 must conatin zero */ +//#define _PAGE_INVALID 0x400 /* HW invalid bit */ +//#define _PAGE_INDEX_SHIFT 12 +//#define _PAGE_OFFSET_MASK 0xffUL /* page table offset mask */ + +#endif /* __sw_64__ */ + #ifdef __ia64__ /* ia64 */ #define REGION_SHIFT (61) @@ -1253,6 +1294,21 @@ #define arch_crashkernel_mem_size() stub_false() #endif /* s390x */ +#ifdef __sw_64__ /* sw_64 */ +int get_machdep_info_sw_64(void); +unsigned long long vaddr_to_paddr_sw_64(unsigned long vaddr); +//int is_iomem_phys_addr_s390x(unsigned long addr); +#define find_vmemmap() stub_false() +#define get_phys_base() stub_true() +#define get_machdep_info() get_machdep_info_sw_64() +#define get_versiondep_info() stub_true() +#define get_kaslr_offset(X) stub_false() +#define vaddr_to_paddr(X) vaddr_to_paddr_sw_64(X) +#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) +#define is_phys_addr(X) stub_true_ul(X) +#define arch_crashkernel_mem_size() stub_false() +#endif /* sw_64 */ + #ifdef __ia64__ /* ia64 */ int get_phys_base_ia64(void); int get_machdep_info_ia64(void); @@ -2504,6 +2560,12 @@ #define get_xen_info_arch(X) FALSE #endif /* s390x */ +#ifdef __sw_64__ /* sw_64 */ +#define kvtop_xen(X) FALSE +#define get_xen_basic_info_arch(X) FALSE +#define get_xen_info_arch(X) FALSE +#endif /* sw_64 */ + #ifdef __sparc64__ /* sparc64 */ #define kvtop_xen(X) FALSE #define get_xen_basic_info_arch(X) FALSE diff -Naru ./makedumpfile-1.7.4/Makefile ./makedumpfile-1.7.4-sw64/Makefile --- ./makedumpfile-1.7.4/Makefile 2025-04-01 08:34:04.978967628 +0800 +++ ./makedumpfile-1.7.4-sw64/Makefile 2025-04-01 08:37:38.886978748 +0800 @@ -47,7 +48,7 @@ SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c detect_cycle.c OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) -SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c arch/mips64.c arch/loongarch64.c arch/riscv64.c +SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c arch/mips64.c arch/loongarch64.c arch/riscv64.c arch/sw_64.c OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) LIBS = -ldw -lbz2 -ldl -lelf -lz