Commit dd55dd0d authored by Huacai Chen's avatar Huacai Chen
Browse files

LoongArch: Adjust memory management for 32BIT/64BIT



Adjust memory management for both 32BIT and 64BIT, including: address
space definition, DMW CSR definition, page table bits definition, boot
time detection of VA/PA bits, page table init, tlb exception handling,
copy_page/clear_page/dump_tlb libraries, etc.

Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: default avatarYawei Li <liyawei@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 7b2afeaf
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -38,11 +38,20 @@ extern unsigned long vm_map_base;
#endif

#ifndef WRITECOMBINE_BASE
#ifdef CONFIG_32BIT
#define WRITECOMBINE_BASE	CSR_DMW0_BASE
#else
#define WRITECOMBINE_BASE	CSR_DMW2_BASE
#endif
#endif

#ifdef CONFIG_32BIT
#define DMW_PABITS	29
#define TO_PHYS_MASK	((_UL(1) << _UL(DMW_PABITS)) - 1)
#else
#define DMW_PABITS	48
#define TO_PHYS_MASK	((_ULL(1) << _ULL(DMW_PABITS)) - 1)
#endif

/*
 * Memory above this physical address will be considered highmem.
@@ -112,7 +121,11 @@ extern unsigned long vm_map_base;
/*
 * Returns the physical address of a KPRANGEx / XKPRANGE address
 */
#ifdef CONFIG_32BIT
#define PHYSADDR(a)		((_ACAST32_(a)) & TO_PHYS_MASK)
#else
#define PHYSADDR(a)		((_ACAST64_(a)) & TO_PHYS_MASK)
#endif

/*
 * On LoongArch, I/O ports mappring is following:
+0 −3
Original line number Diff line number Diff line
@@ -20,16 +20,13 @@
#define cpu_has_loongarch64		(cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT)

#ifdef CONFIG_32BIT
# define cpu_has_64bits			(cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT)
# define cpu_vabits			31
# define cpu_pabits			31
#endif

#ifdef CONFIG_64BIT
# define cpu_has_64bits			1
# define cpu_vabits			cpu_data[0].vabits
# define cpu_pabits			cpu_data[0].pabits
# define __NEED_ADDRBITS_PROBE
#endif

/*
+24 −0
Original line number Diff line number Diff line
@@ -912,6 +912,26 @@
#define LOONGARCH_CSR_DMWIN3		0x183	/* 64 direct map win3: MEM */

/* Direct Map window 0/1/2/3 */

#ifdef CONFIG_32BIT

#define CSR_DMW0_PLV0		(1 << 0)
#define CSR_DMW0_VSEG		(0x4)
#define CSR_DMW0_BASE		(CSR_DMW0_VSEG << DMW_PABITS)
#define CSR_DMW0_INIT		(CSR_DMW0_BASE | CSR_DMW0_PLV0)

#define CSR_DMW1_PLV0		(1 << 0)
#define CSR_DMW1_MAT		(1 << 4)
#define CSR_DMW1_VSEG		(0x5)
#define CSR_DMW1_BASE		(CSR_DMW1_VSEG << DMW_PABITS)
#define CSR_DMW1_INIT		(CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0)

#define CSR_DMW2_INIT		0x0

#define CSR_DMW3_INIT		0x0

#else

#define CSR_DMW0_PLV0		_CONST64_(1 << 0)
#define CSR_DMW0_VSEG		_CONST64_(0x8000)
#define CSR_DMW0_BASE		(CSR_DMW0_VSEG << DMW_PABITS)
@@ -931,6 +951,8 @@

#define CSR_DMW3_INIT		0x0

#endif

/* Performance Counter registers */
#define LOONGARCH_CSR_PERFCTRL0		0x200	/* 32 perf event 0 config */
#define LOONGARCH_CSR_PERFCNTR0		0x201	/* 64 perf event 0 count value */
@@ -1388,8 +1410,10 @@ __BUILD_CSR_OP(tlbidx)
#define ENTRYLO_C_SHIFT		4
#define ENTRYLO_C		(_ULCAST_(3) << ENTRYLO_C_SHIFT)
#define ENTRYLO_G		(_ULCAST_(1) << 6)
#ifdef CONFIG_64BIT
#define ENTRYLO_NR		(_ULCAST_(1) << 61)
#define ENTRYLO_NX		(_ULCAST_(1) << 62)
#endif

/* Values for PageSize register */
#define PS_4K		0x0000000c
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@

#include <vdso/page.h>

#define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
#define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - PTRLOG)
#define HPAGE_SIZE	(_AC(1, UL) << HPAGE_SHIFT)
#define HPAGE_MASK	(~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+34 −2
Original line number Diff line number Diff line
@@ -6,6 +6,26 @@
#define _ASM_PGTABLE_BITS_H

/* Page table bits */

#ifdef CONFIG_32BIT
#define	_PAGE_VALID_SHIFT	0
#define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
#define	_PAGE_DIRTY_SHIFT	1
#define	_PAGE_PLV_SHIFT		2  /* 2~3, two bits */
#define	_CACHE_SHIFT		4  /* 4~5, two bits */
#define	_PAGE_GLOBAL_SHIFT	6
#define	_PAGE_HUGE_SHIFT	6  /* HUGE is a PMD bit */
#define	_PAGE_PRESENT_SHIFT	7
#define	_PAGE_PFN_SHIFT		8
#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
#define	_PAGE_SWP_EXCLUSIVE_SHIFT 13
#define	_PAGE_PFN_END_SHIFT	28
#define	_PAGE_WRITE_SHIFT	29
#define	_PAGE_MODIFIED_SHIFT	30
#define	_PAGE_PRESENT_INVALID_SHIFT 31
#endif

#ifdef CONFIG_64BIT
#define	_PAGE_VALID_SHIFT	0
#define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
#define	_PAGE_DIRTY_SHIFT	1
@@ -18,14 +38,15 @@
#define	_PAGE_MODIFIED_SHIFT	9
#define	_PAGE_PROTNONE_SHIFT	10
#define	_PAGE_SPECIAL_SHIFT	11
#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
#define	_PAGE_PFN_SHIFT		12
#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
#define	_PAGE_SWP_EXCLUSIVE_SHIFT 23
#define	_PAGE_PFN_END_SHIFT	48
#define	_PAGE_PRESENT_INVALID_SHIFT 60
#define	_PAGE_NO_READ_SHIFT	61
#define	_PAGE_NO_EXEC_SHIFT	62
#define	_PAGE_RPLV_SHIFT	63
#endif

/* Used by software */
#define _PAGE_PRESENT		(_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
@@ -33,10 +54,15 @@
#define _PAGE_WRITE		(_ULCAST_(1) << _PAGE_WRITE_SHIFT)
#define _PAGE_ACCESSED		(_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
#define _PAGE_MODIFIED		(_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
#ifdef CONFIG_32BIT
#define _PAGE_PROTNONE		0
#define _PAGE_SPECIAL		0
#else
#define _PAGE_PROTNONE		(_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
#define _PAGE_SPECIAL		(_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
#endif

/* We borrow bit 23 to store the exclusive marker in swap PTEs. */
/* We borrow bit 13/23 to store the exclusive marker in swap PTEs. */
#define _PAGE_SWP_EXCLUSIVE	(_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT)

/* Used by TLB hardware (placed in EntryLo*) */
@@ -46,9 +72,15 @@
#define _PAGE_GLOBAL		(_ULCAST_(1) << _PAGE_GLOBAL_SHIFT)
#define _PAGE_HUGE		(_ULCAST_(1) << _PAGE_HUGE_SHIFT)
#define _PAGE_HGLOBAL		(_ULCAST_(1) << _PAGE_HGLOBAL_SHIFT)
#ifdef CONFIG_32BIT
#define _PAGE_NO_READ		0
#define _PAGE_NO_EXEC		0
#define _PAGE_RPLV		0
#else
#define _PAGE_NO_READ		(_ULCAST_(1) << _PAGE_NO_READ_SHIFT)
#define _PAGE_NO_EXEC		(_ULCAST_(1) << _PAGE_NO_EXEC_SHIFT)
#define _PAGE_RPLV		(_ULCAST_(1) << _PAGE_RPLV_SHIFT)
#endif
#define _CACHE_MASK		(_ULCAST_(3) << _CACHE_SHIFT)
#define PFN_PTE_SHIFT		(PAGE_SHIFT - 12 + _PAGE_PFN_SHIFT)

Loading