All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] makedumpfile: Add initial mips64 support
@ 2021-01-19  1:17 Youling Tang
  2021-01-29  6:13 ` HAGIO KAZUHITO(萩尾 一仁)
  0 siblings, 1 reply; 3+ messages in thread
From: Youling Tang @ 2021-01-19  1:17 UTC (permalink / raw)
  To: Kazuhito Hagio; +Cc: Jinyang He, Youling Tang, kexec-ml, Huacai Chen

Patch adds support for mips64 in makedumpfile. It takes care of vmalloc,
module and directly map kernel memory region's translation. Currently we
only support 3 leverl 16K pages and VA_BITS as 48.

The changes were tested on a mips64 Loongson-3A4000 processor. The dump
compression and filtering (for all dump levels 1,2,4,8,16 and 31) tests
are succussfull.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 Makefile       |   2 +-
 arch/mips64.c  | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |  54 +++++++++++++++++++++++++++
 3 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips64.c

diff --git a/Makefile b/Makefile
index cb6bd42..6f8ade0 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ endif
 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
 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
+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
 OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
 
 LIBS = -ldw -lbz2 -ldl -lelf -lz
diff --git a/arch/mips64.c b/arch/mips64.c
new file mode 100644
index 0000000..18a9e05
--- /dev/null
+++ b/arch/mips64.c
@@ -0,0 +1,113 @@
+/*
+ * mips64.c
+ *
+ * Copyright (C) 2021 Loongson Technology Co., Ltd.
+ *
+ * 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 __mips64__
+
+#include "../print_info.h"
+#include "../elf_info.h"
+#include "../makedumpfile.h"
+
+int
+get_phys_base_mips64(void)
+{
+	info->phys_base = 0ULL;
+
+	DEBUG_MSG("phys_base    : %lx\n", info->phys_base);
+
+	return TRUE;
+}
+
+int
+get_versiondep_info_mips64(void)
+{
+	info->page_offset  = 0x9800000000000000ULL;
+	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
+	info->section_size_bits = _SECTION_SIZE_BITS;
+
+	DEBUG_MSG("page_offset : %lx\n", info->page_offset);
+	DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
+	DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
+
+	return TRUE;
+}
+
+/*
+ * Translate a virtual address to a physical address by using 3 levels paging.
+ */
+unsigned long long
+vaddr_to_paddr_mips64(unsigned long vaddr)
+{
+	unsigned long long paddr = NOT_PADDR;
+	pgd_t	*pgda, pgdv;
+	pmd_t	*pmda, pmdv;
+	pte_t 	*ptea, ptev;
+
+	/*
+	 * CKSEG0/CKSEG1
+	 */
+	if (vaddr >= 0xffffffff80000000ULL && vaddr < 0xffffffffc0000000ULL)
+		return vaddr & 0x1fffffffULL;
+
+	/*
+	 * XKPHYS
+	 */
+	if (vaddr >= 0x9000000000000000ULL && vaddr < 0xc000000000000000ULL)
+		return vaddr & ((1ULL << MAX_PHYSMEM_BITS()) - 1);
+
+	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
+		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
+		return NOT_PADDR;
+	}
+
+	pgda = pgd_offset(SYMBOL(swapper_pg_dir), vaddr);
+	if (!readmem(PADDR, (unsigned long long)pgda, &pgdv, sizeof(pgdv))) {
+		ERRMSG("Can't read pgd\n");
+		return NOT_PADDR;
+	}
+
+	pmda = pmd_offset(&pgdv, vaddr);
+	if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
+		ERRMSG("Can't read pmd\n");
+		return NOT_PADDR;
+	}
+
+	switch (pmdv & (_PAGE_PRESENT|_PAGE_HUGE)) {
+	case _PAGE_PRESENT:
+		ptea = pte_offset(&pmdv, vaddr);
+		/* 64k page */
+		if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) {
+			ERRMSG("Can't read pte\n");
+			return NOT_PADDR;
+		}
+
+		if (!(ptev & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid pte.\n");
+			return NOT_PADDR;
+		} else {
+			paddr = PAGEBASE(ptev) + (vaddr & (PAGESIZE() - 1));
+		}
+		break;
+	case _PAGE_PRESENT|_PAGE_HUGE:
+		paddr = (pmdv & PMD_MASK) + (vaddr & (PMD_SIZE - 1));
+		break;
+	}
+
+	return paddr;
+}
+
+#endif /* mips64 */
diff --git a/makedumpfile.h b/makedumpfile.h
index 5f50080..bc86bf2 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -958,6 +958,39 @@ typedef unsigned long pgd_t;
 
 #endif          /* sparc64 */
 
+#ifdef __mips64__ /* mips64 */
+#define KVBASE			PAGE_OFFSET
+#define _SECTION_SIZE_BITS	(28)
+#define _MAX_PHYSMEM_BITS	(48)
+#define _PAGE_PRESENT		(1 << 0)
+#define _PAGE_HUGE		(1 << 4)
+
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+
+#define PAGE_MASK		(~(PAGESIZE() - 1))
+#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PMD_SHIFT		((PAGESHIFT() - 3) * 2 + 3)
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PGDIR_SHIFT		((PAGESHIFT() - 3) * 3 + 3)
+#define PTRS_PER_PTE		(1 << (PAGESHIFT() - 3))
+#define PTRS_PER_PMD		PTRS_PER_PTE
+#define PTRS_PER_PGD		PTRS_PER_PTE
+
+#define pte_index(vaddr)		(((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
+#define pmd_page_paddr(pmd)		(pmd & (int32_t)PAGE_MASK)
+#define pte_offset(dir, vaddr)		((pte_t *)pmd_page_paddr((*dir)) + pte_index(vaddr))
+
+#define pmd_index(vaddr)		(((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+#define pgd_page_paddr(pgd)		(pgd & (int32_t)PAGE_MASK)
+#define pmd_offset(pgd, vaddr)		((pmd_t *)pgd_page_paddr((*pgd)) + pmd_index(vaddr))
+
+#define pgd_index(vaddr)		(((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_offset(pgdir, vaddr)	((pgd_t *)(pgdir) + pgd_index(vaddr))
+
+#endif		/* mips64 */
+
 /*
  * The function of dependence on machine
  */
@@ -1112,6 +1145,21 @@ unsigned long long vaddr_to_paddr_sparc64(unsigned long vaddr);
 #define arch_crashkernel_mem_size()	stub_false()
 #endif		/* sparc64 */
 
+#ifdef __mips64__ /* mips64 */
+int get_phys_base_mips64(void);
+int get_versiondep_info_mips64(void);
+unsigned long long vaddr_to_paddr_mips64(unsigned long vaddr);
+#define find_vmemmap()		stub_false()
+#define get_phys_base() 	get_phys_base_mips64()
+#define get_machdep_info()	stub_true()
+#define get_versiondep_info()	get_versiondep_info_mips64()
+#define get_kaslr_offset(X)	stub_false()
+#define vaddr_to_paddr(X)	vaddr_to_paddr_mips64(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		/* mips64 */
+
 typedef unsigned long long mdf_pfn_t;
 
 #ifndef ARCH_PFN_OFFSET
@@ -2228,6 +2276,12 @@ int get_xen_info_ia64(void);
 #define get_xen_info_arch(X) FALSE
 #endif	/* sparc64 */
 
+#ifdef __mips64__ /* mips64 */
+#define kvtop_xen(X)	FALSE
+#define get_xen_basic_info_arch(X) FALSE
+#define get_xen_info_arch(X) FALSE
+#endif	/* mips64 */
+
 struct cycle {
 	mdf_pfn_t start_pfn;
 	mdf_pfn_t end_pfn;
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [PATCH] makedumpfile: Add initial mips64 support
  2021-01-19  1:17 [PATCH] makedumpfile: Add initial mips64 support Youling Tang
@ 2021-01-29  6:13 ` HAGIO KAZUHITO(萩尾 一仁)
  2021-01-29  7:44   ` Youling Tang
  0 siblings, 1 reply; 3+ messages in thread
From: HAGIO KAZUHITO(萩尾 一仁) @ 2021-01-29  6:13 UTC (permalink / raw)
  To: Youling Tang; +Cc: Jinyang He, kexec-ml, Huacai Chen

Hi Yuling Tang,

-----Original Message-----
> Patch adds support for mips64 in makedumpfile. It takes care of vmalloc,
> module and directly map kernel memory region's translation. Currently we
> only support 3 leverl 16K pages and VA_BITS as 48.
> 
> The changes were tested on a mips64 Loongson-3A4000 processor. The dump
> compression and filtering (for all dump levels 1,2,4,8,16 and 31) tests
> are succussfull.
> 
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> Signed-off-by: Jinyang He <hejinyang@loongson.cn>
> Signed-off-by: Youling Tang <tangyouling@loongson.cn>
> ---
>  Makefile       |   2 +-
>  arch/mips64.c  | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  makedumpfile.h |  54 +++++++++++++++++++++++++++
>  3 files changed, 168 insertions(+), 1 deletion(-)
>  create mode 100644 arch/mips64.c
> 
> diff --git a/Makefile b/Makefile
> index cb6bd42..6f8ade0 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -47,7 +47,7 @@ endif
>  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
>  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
> +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
>  OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
> 
>  LIBS = -ldw -lbz2 -ldl -lelf -lz
> diff --git a/arch/mips64.c b/arch/mips64.c
> new file mode 100644
> index 0000000..18a9e05
> --- /dev/null
> +++ b/arch/mips64.c
> @@ -0,0 +1,113 @@
> +/*
> + * mips64.c
> + *
> + * Copyright (C) 2021 Loongson Technology Co., Ltd.
> + *
> + * 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 __mips64__
> +
> +#include "../print_info.h"
> +#include "../elf_info.h"
> +#include "../makedumpfile.h"
> +
> +int
> +get_phys_base_mips64(void)
> +{
> +	info->phys_base = 0ULL;
> +
> +	DEBUG_MSG("phys_base    : %lx\n", info->phys_base);
> +
> +	return TRUE;
> +}
> +
> +int
> +get_versiondep_info_mips64(void)
> +{
> +	info->page_offset  = 0x9800000000000000ULL;
> +	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
> +	info->section_size_bits = _SECTION_SIZE_BITS;
> +
> +	DEBUG_MSG("page_offset : %lx\n", info->page_offset);
> +	DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
> +	DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
> +
> +	return TRUE;
> +}
> +
> +/*
> + * Translate a virtual address to a physical address by using 3 levels paging.
> + */
> +unsigned long long
> +vaddr_to_paddr_mips64(unsigned long vaddr)
> +{
> +	unsigned long long paddr = NOT_PADDR;
> +	pgd_t	*pgda, pgdv;
> +	pmd_t	*pmda, pmdv;
> +	pte_t 	*ptea, ptev;
> +
> +	/*
> +	 * CKSEG0/CKSEG1
> +	 */
> +	if (vaddr >= 0xffffffff80000000ULL && vaddr < 0xffffffffc0000000ULL)
> +		return vaddr & 0x1fffffffULL;
> +
> +	/*
> +	 * XKPHYS
> +	 */
> +	if (vaddr >= 0x9000000000000000ULL && vaddr < 0xc000000000000000ULL)
> +		return vaddr & ((1ULL << MAX_PHYSMEM_BITS()) - 1);

From the current implementation, vaddr_to_paddr() is called the first time
in the context of:

initial()
  get_machdep_info()
  calibrate_machdep_info()
  check_release()
    readmem()
      vaddr_to_paddr()
  get_versiondep_info()

So setting info->max_physmem_bits in get_versiondep_info() is late,
but it might work because
- The address that the readmem() reads is SYMBOL(init_uts_ns), so
  this XKPHYS condition does not match,  or/and
- 5.9+ kernels have NUMBER(MAX_PHYSMEM_BITS) entry in vmcoreinfo, so
  info->max_physmem_bits is set in calibrate_machdep_info().

So I would suggest moving max_physmem_bits and section_size_bits to
get_machdep_info() for future changes and to not confuse readers.. (including me :-)

Otherwise, looks good to me.  Thank you for using makedumpfile!

Kazu

> +
> +	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
> +		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
> +		return NOT_PADDR;
> +	}
> +
> +	pgda = pgd_offset(SYMBOL(swapper_pg_dir), vaddr);
> +	if (!readmem(PADDR, (unsigned long long)pgda, &pgdv, sizeof(pgdv))) {
> +		ERRMSG("Can't read pgd\n");
> +		return NOT_PADDR;
> +	}
> +
> +	pmda = pmd_offset(&pgdv, vaddr);
> +	if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
> +		ERRMSG("Can't read pmd\n");
> +		return NOT_PADDR;
> +	}
> +
> +	switch (pmdv & (_PAGE_PRESENT|_PAGE_HUGE)) {
> +	case _PAGE_PRESENT:
> +		ptea = pte_offset(&pmdv, vaddr);
> +		/* 64k page */
> +		if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) {
> +			ERRMSG("Can't read pte\n");
> +			return NOT_PADDR;
> +		}
> +
> +		if (!(ptev & _PAGE_PRESENT)) {
> +			ERRMSG("Can't get a valid pte.\n");
> +			return NOT_PADDR;
> +		} else {
> +			paddr = PAGEBASE(ptev) + (vaddr & (PAGESIZE() - 1));
> +		}
> +		break;
> +	case _PAGE_PRESENT|_PAGE_HUGE:
> +		paddr = (pmdv & PMD_MASK) + (vaddr & (PMD_SIZE - 1));
> +		break;
> +	}
> +
> +	return paddr;
> +}
> +
> +#endif /* mips64 */
> diff --git a/makedumpfile.h b/makedumpfile.h
> index 5f50080..bc86bf2 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -958,6 +958,39 @@ typedef unsigned long pgd_t;
> 
>  #endif          /* sparc64 */
> 
> +#ifdef __mips64__ /* mips64 */
> +#define KVBASE			PAGE_OFFSET
> +#define _SECTION_SIZE_BITS	(28)
> +#define _MAX_PHYSMEM_BITS	(48)
> +#define _PAGE_PRESENT		(1 << 0)
> +#define _PAGE_HUGE		(1 << 4)
> +
> +typedef unsigned long pte_t;
> +typedef unsigned long pmd_t;
> +typedef unsigned long pgd_t;
> +
> +#define PAGE_MASK		(~(PAGESIZE() - 1))
> +#define PMD_MASK		(~(PMD_SIZE - 1))
> +#define PMD_SHIFT		((PAGESHIFT() - 3) * 2 + 3)
> +#define PMD_SIZE		(1UL << PMD_SHIFT)
> +#define PGDIR_SHIFT		((PAGESHIFT() - 3) * 3 + 3)
> +#define PTRS_PER_PTE		(1 << (PAGESHIFT() - 3))
> +#define PTRS_PER_PMD		PTRS_PER_PTE
> +#define PTRS_PER_PGD		PTRS_PER_PTE
> +
> +#define pte_index(vaddr)		(((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
> +#define pmd_page_paddr(pmd)		(pmd & (int32_t)PAGE_MASK)
> +#define pte_offset(dir, vaddr)		((pte_t *)pmd_page_paddr((*dir)) + pte_index(vaddr))
> +
> +#define pmd_index(vaddr)		(((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
> +#define pgd_page_paddr(pgd)		(pgd & (int32_t)PAGE_MASK)
> +#define pmd_offset(pgd, vaddr)		((pmd_t *)pgd_page_paddr((*pgd)) + pmd_index(vaddr))
> +
> +#define pgd_index(vaddr)		(((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
> +#define pgd_offset(pgdir, vaddr)	((pgd_t *)(pgdir) + pgd_index(vaddr))
> +
> +#endif		/* mips64 */
> +
>  /*
>   * The function of dependence on machine
>   */
> @@ -1112,6 +1145,21 @@ unsigned long long vaddr_to_paddr_sparc64(unsigned long vaddr);
>  #define arch_crashkernel_mem_size()	stub_false()
>  #endif		/* sparc64 */
> 
> +#ifdef __mips64__ /* mips64 */
> +int get_phys_base_mips64(void);
> +int get_versiondep_info_mips64(void);
> +unsigned long long vaddr_to_paddr_mips64(unsigned long vaddr);
> +#define find_vmemmap()		stub_false()
> +#define get_phys_base() 	get_phys_base_mips64()
> +#define get_machdep_info()	stub_true()
> +#define get_versiondep_info()	get_versiondep_info_mips64()
> +#define get_kaslr_offset(X)	stub_false()
> +#define vaddr_to_paddr(X)	vaddr_to_paddr_mips64(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		/* mips64 */
> +
>  typedef unsigned long long mdf_pfn_t;
> 
>  #ifndef ARCH_PFN_OFFSET
> @@ -2228,6 +2276,12 @@ int get_xen_info_ia64(void);
>  #define get_xen_info_arch(X) FALSE
>  #endif	/* sparc64 */
> 
> +#ifdef __mips64__ /* mips64 */
> +#define kvtop_xen(X)	FALSE
> +#define get_xen_basic_info_arch(X) FALSE
> +#define get_xen_info_arch(X) FALSE
> +#endif	/* mips64 */
> +
>  struct cycle {
>  	mdf_pfn_t start_pfn;
>  	mdf_pfn_t end_pfn;
> --
> 2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] makedumpfile: Add initial mips64 support
  2021-01-29  6:13 ` HAGIO KAZUHITO(萩尾 一仁)
@ 2021-01-29  7:44   ` Youling Tang
  0 siblings, 0 replies; 3+ messages in thread
From: Youling Tang @ 2021-01-29  7:44 UTC (permalink / raw)
  To: HAGIO KAZUHITO(萩尾 一仁)
  Cc: Jinyang He, kexec-ml, Huacai Chen

Hi HAGIO KAZUHITO,

On 01/29/2021 02:13 PM, HAGIO KAZUHITO(萩尾 一仁) wrote:
> Hi Yuling Tang,
>
> -----Original Message-----
>> Patch adds support for mips64 in makedumpfile. It takes care of vmalloc,
>> module and directly map kernel memory region's translation. Currently we
>> only support 3 leverl 16K pages and VA_BITS as 48.
>>
>> The changes were tested on a mips64 Loongson-3A4000 processor. The dump
>> compression and filtering (for all dump levels 1,2,4,8,16 and 31) tests
>> are succussfull.
>>
>> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
>> Signed-off-by: Jinyang He <hejinyang@loongson.cn>
>> Signed-off-by: Youling Tang <tangyouling@loongson.cn>
>> ---
>>   Makefile       |   2 +-
>>   arch/mips64.c  | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   makedumpfile.h |  54 +++++++++++++++++++++++++++
>>   3 files changed, 168 insertions(+), 1 deletion(-)
>>   create mode 100644 arch/mips64.c
>>
>> diff --git a/Makefile b/Makefile
>> index cb6bd42..6f8ade0 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -47,7 +47,7 @@ endif
>>   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
>>   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
>> +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
>>   OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
>>
>>   LIBS = -ldw -lbz2 -ldl -lelf -lz
>> diff --git a/arch/mips64.c b/arch/mips64.c
>> new file mode 100644
>> index 0000000..18a9e05
>> --- /dev/null
>> +++ b/arch/mips64.c
>> @@ -0,0 +1,113 @@
>> +/*
>> + * mips64.c
>> + *
>> + * Copyright (C) 2021 Loongson Technology Co., Ltd.
>> + *
>> + * 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 __mips64__
>> +
>> +#include "../print_info.h"
>> +#include "../elf_info.h"
>> +#include "../makedumpfile.h"
>> +
>> +int
>> +get_phys_base_mips64(void)
>> +{
>> +	info->phys_base = 0ULL;
>> +
>> +	DEBUG_MSG("phys_base    : %lx\n", info->phys_base);
>> +
>> +	return TRUE;
>> +}
>> +
>> +int
>> +get_versiondep_info_mips64(void)
>> +{
>> +	info->page_offset  = 0x9800000000000000ULL;
>> +	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
>> +	info->section_size_bits = _SECTION_SIZE_BITS;
>> +
>> +	DEBUG_MSG("page_offset : %lx\n", info->page_offset);
>> +	DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
>> +	DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
>> +
>> +	return TRUE;
>> +}
>> +
>> +/*
>> + * Translate a virtual address to a physical address by using 3 levels paging.
>> + */
>> +unsigned long long
>> +vaddr_to_paddr_mips64(unsigned long vaddr)
>> +{
>> +	unsigned long long paddr = NOT_PADDR;
>> +	pgd_t	*pgda, pgdv;
>> +	pmd_t	*pmda, pmdv;
>> +	pte_t 	*ptea, ptev;
>> +
>> +	/*
>> +	 * CKSEG0/CKSEG1
>> +	 */
>> +	if (vaddr >= 0xffffffff80000000ULL && vaddr < 0xffffffffc0000000ULL)
>> +		return vaddr & 0x1fffffffULL;
>> +
>> +	/*
>> +	 * XKPHYS
>> +	 */
>> +	if (vaddr >= 0x9000000000000000ULL && vaddr < 0xc000000000000000ULL)
>> +		return vaddr & ((1ULL << MAX_PHYSMEM_BITS()) - 1);
>  From the current implementation, vaddr_to_paddr() is called the first time
> in the context of:
>
> initial()
>    get_machdep_info()
>    calibrate_machdep_info()
>    check_release()
>      readmem()
>        vaddr_to_paddr()
>    get_versiondep_info()
>
> So setting info->max_physmem_bits in get_versiondep_info() is late,
> but it might work because
> - The address that the readmem() reads is SYMBOL(init_uts_ns), so
>    this XKPHYS condition does not match,  or/and
> - 5.9+ kernels have NUMBER(MAX_PHYSMEM_BITS) entry in vmcoreinfo, so
>    info->max_physmem_bits is set in calibrate_machdep_info().
>
> So I would suggest moving max_physmem_bits and section_size_bits to
> get_machdep_info() for future changes and to not confuse readers.. (including me :-)
>
> Otherwise, looks good to me.  Thank you for using makedumpfile!
Thank you for your reply and suggestions.
I will move max_physmem_bits and section_size_bits to
get_machdep_info_mips64() in V2.

Thanks,
Youling.
>
> Kazu
>
>> +
>> +	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
>> +		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
>> +		return NOT_PADDR;
>> +	}
>> +
>> +	pgda = pgd_offset(SYMBOL(swapper_pg_dir), vaddr);
>> +	if (!readmem(PADDR, (unsigned long long)pgda, &pgdv, sizeof(pgdv))) {
>> +		ERRMSG("Can't read pgd\n");
>> +		return NOT_PADDR;
>> +	}
>> +
>> +	pmda = pmd_offset(&pgdv, vaddr);
>> +	if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
>> +		ERRMSG("Can't read pmd\n");
>> +		return NOT_PADDR;
>> +	}
>> +
>> +	switch (pmdv & (_PAGE_PRESENT|_PAGE_HUGE)) {
>> +	case _PAGE_PRESENT:
>> +		ptea = pte_offset(&pmdv, vaddr);
>> +		/* 64k page */
>> +		if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) {
>> +			ERRMSG("Can't read pte\n");
>> +			return NOT_PADDR;
>> +		}
>> +
>> +		if (!(ptev & _PAGE_PRESENT)) {
>> +			ERRMSG("Can't get a valid pte.\n");
>> +			return NOT_PADDR;
>> +		} else {
>> +			paddr = PAGEBASE(ptev) + (vaddr & (PAGESIZE() - 1));
>> +		}
>> +		break;
>> +	case _PAGE_PRESENT|_PAGE_HUGE:
>> +		paddr = (pmdv & PMD_MASK) + (vaddr & (PMD_SIZE - 1));
>> +		break;
>> +	}
>> +
>> +	return paddr;
>> +}
>> +
>> +#endif /* mips64 */
>> diff --git a/makedumpfile.h b/makedumpfile.h
>> index 5f50080..bc86bf2 100644
>> --- a/makedumpfile.h
>> +++ b/makedumpfile.h
>> @@ -958,6 +958,39 @@ typedef unsigned long pgd_t;
>>
>>   #endif          /* sparc64 */
>>
>> +#ifdef __mips64__ /* mips64 */
>> +#define KVBASE			PAGE_OFFSET
>> +#define _SECTION_SIZE_BITS	(28)
>> +#define _MAX_PHYSMEM_BITS	(48)
>> +#define _PAGE_PRESENT		(1 << 0)
>> +#define _PAGE_HUGE		(1 << 4)
>> +
>> +typedef unsigned long pte_t;
>> +typedef unsigned long pmd_t;
>> +typedef unsigned long pgd_t;
>> +
>> +#define PAGE_MASK		(~(PAGESIZE() - 1))
>> +#define PMD_MASK		(~(PMD_SIZE - 1))
>> +#define PMD_SHIFT		((PAGESHIFT() - 3) * 2 + 3)
>> +#define PMD_SIZE		(1UL << PMD_SHIFT)
>> +#define PGDIR_SHIFT		((PAGESHIFT() - 3) * 3 + 3)
>> +#define PTRS_PER_PTE		(1 << (PAGESHIFT() - 3))
>> +#define PTRS_PER_PMD		PTRS_PER_PTE
>> +#define PTRS_PER_PGD		PTRS_PER_PTE
>> +
>> +#define pte_index(vaddr)		(((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
>> +#define pmd_page_paddr(pmd)		(pmd & (int32_t)PAGE_MASK)
>> +#define pte_offset(dir, vaddr)		((pte_t *)pmd_page_paddr((*dir)) + pte_index(vaddr))
>> +
>> +#define pmd_index(vaddr)		(((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
>> +#define pgd_page_paddr(pgd)		(pgd & (int32_t)PAGE_MASK)
>> +#define pmd_offset(pgd, vaddr)		((pmd_t *)pgd_page_paddr((*pgd)) + pmd_index(vaddr))
>> +
>> +#define pgd_index(vaddr)		(((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
>> +#define pgd_offset(pgdir, vaddr)	((pgd_t *)(pgdir) + pgd_index(vaddr))
>> +
>> +#endif		/* mips64 */
>> +
>>   /*
>>    * The function of dependence on machine
>>    */
>> @@ -1112,6 +1145,21 @@ unsigned long long vaddr_to_paddr_sparc64(unsigned long vaddr);
>>   #define arch_crashkernel_mem_size()	stub_false()
>>   #endif		/* sparc64 */
>>
>> +#ifdef __mips64__ /* mips64 */
>> +int get_phys_base_mips64(void);
>> +int get_versiondep_info_mips64(void);
>> +unsigned long long vaddr_to_paddr_mips64(unsigned long vaddr);
>> +#define find_vmemmap()		stub_false()
>> +#define get_phys_base() 	get_phys_base_mips64()
>> +#define get_machdep_info()	stub_true()
>> +#define get_versiondep_info()	get_versiondep_info_mips64()
>> +#define get_kaslr_offset(X)	stub_false()
>> +#define vaddr_to_paddr(X)	vaddr_to_paddr_mips64(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		/* mips64 */
>> +
>>   typedef unsigned long long mdf_pfn_t;
>>
>>   #ifndef ARCH_PFN_OFFSET
>> @@ -2228,6 +2276,12 @@ int get_xen_info_ia64(void);
>>   #define get_xen_info_arch(X) FALSE
>>   #endif	/* sparc64 */
>>
>> +#ifdef __mips64__ /* mips64 */
>> +#define kvtop_xen(X)	FALSE
>> +#define get_xen_basic_info_arch(X) FALSE
>> +#define get_xen_info_arch(X) FALSE
>> +#endif	/* mips64 */
>> +
>>   struct cycle {
>>   	mdf_pfn_t start_pfn;
>>   	mdf_pfn_t end_pfn;
>> --
>> 2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-01-29  7:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-19  1:17 [PATCH] makedumpfile: Add initial mips64 support Youling Tang
2021-01-29  6:13 ` HAGIO KAZUHITO(萩尾 一仁)
2021-01-29  7:44   ` Youling Tang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.