[PATCH] [yeeloong] Kernel support for non-4K pages

Vladimir 'φ-coder/phcoder' Serbinenko phcoder at gmail.com
Mon Sep 27 11:07:50 UTC 2010


On 09/27/2010 09:10 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> Loongson CPUs have an annoying VIPT cache and 14 bits of virtual address
> are used for tagging. So either we need an excessive and difficult to
> maintain cache flushing or to use 16K or biger pages. Note than when
> configuring Linux on Yeeloong only page size of 16K and 64K are proposed.
> This patch fixes bunch of hardcoding of page size related constants and
> changes PAGE_SHIFT to 14 on Yeeloong.
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

-------------- next part --------------
=== modified file 'mips/include/param.h'
--- mips/include/param.h	2010-08-13 22:16:49 +0000
+++ mips/include/param.h	2010-08-16 23:24:43 +0000
@@ -100,7 +100,11 @@
 #define	CACHE_LINE_SHIFT	6
 #define	CACHE_LINE_SIZE		(1 << CACHE_LINE_SHIFT)
 
+#ifndef TARGET_YEELOONG
 #define	PAGE_SHIFT	12		/* LOG2(PAGE_SIZE) */
+#else
+#define	PAGE_SHIFT	14		/* LOG2(PAGE_SIZE) */
+#endif
 #define	PAGE_SIZE	(1<<PAGE_SHIFT) /* bytes/page */
 #define	PAGE_MASK	(PAGE_SIZE-1)
 

=== modified file 'mips/include/pte.h'
--- mips/include/pte.h	2010-08-13 22:16:49 +0000
+++ mips/include/pte.h	2010-08-17 03:56:21 +0000
@@ -50,7 +50,7 @@
  * TLB PageMask register.  Has mask bits set above the default, 4K, page mask.
  */
 #define	TLBMASK_SHIFT	(13)
-#define	TLBMASK_MASK	((PAGE_MASK >> TLBMASK_SHIFT) << TLBMASK_SHIFT)
+#define	TLBMASK_MASK	((PAGE_MASK >> (TLBMASK_SHIFT - 1)) << TLBMASK_SHIFT)
 
 /*
  * PFN for EntryLo register.  Upper bits are 0, which is to say that
@@ -63,7 +63,7 @@
  */
 #define	TLBLO_SWBITS_SHIFT	(30)
 #define	TLBLO_SWBITS_MASK	(0x3U << TLBLO_SWBITS_SHIFT)
-#define	TLBLO_PFN_SHIFT		(6)
+#define	TLBLO_PFN_SHIFT		(PAGE_SHIFT - 6)
 #define	TLBLO_PFN_MASK		(0x3FFFFFC0)
 #define	TLBLO_PA_TO_PFN(pa)	((((pa) >> TLB_PAGE_SHIFT) << TLBLO_PFN_SHIFT) & TLBLO_PFN_MASK)
 #define	TLBLO_PFN_TO_PA(pfn)	((vm_paddr_t)((pfn) >> TLBLO_PFN_SHIFT) << TLB_PAGE_SHIFT)
@@ -89,9 +89,7 @@
 #define	TLBHI_R_KERNEL		(0x03UL << TLBHI_R_SHIFT)
 #define	TLBHI_R_MASK		(0x03UL << TLBHI_R_SHIFT)
 #define	TLBHI_VA_R(va)		((va) & TLBHI_R_MASK)
-#define	TLBHI_FILL_SHIFT	40
-#define	TLBHI_VPN2_SHIFT	(TLB_PAGE_SHIFT + 1)
-#define	TLBHI_VPN2_MASK		(((~((1UL << TLBHI_VPN2_SHIFT) - 1)) << (63 - TLBHI_FILL_SHIFT)) >> (63 - TLBHI_FILL_SHIFT))
+#define	TLBHI_VPN2_MASK		(~((1ULL << (TLB_PAGE_SHIFT + 1)) - 1) & ~TLBHI_R_MASK)
 #define	TLBHI_VA_TO_VPN2(va)	((va) & TLBHI_VPN2_MASK)
 #define	TLBHI_ENTRY(va, asid)	((TLBHI_VA_R((va))) /* Region. */ | \
 				 (TLBHI_VA_TO_VPN2((va))) /* VPN2. */ | \

=== modified file 'mips/mips/exception.S'
--- mips/mips/exception.S	2010-08-13 22:16:49 +0000
+++ mips/mips/exception.S	2010-08-17 02:58:48 +0000
@@ -83,10 +83,10 @@
 /* Pointer size and mask for n64 */
 #if defined(__mips_n64)
 #define	PTRSHIFT	3
-#define	PTRMASK		0xff8
+#define	PTRMASK         (TLB_PAGE_MASK & ~7)
 #else
 #define	PTRSHIFT	2
-#define	PTRMASK		0xffc
+#define	PTRMASK		(TLB_PAGE_MASK & ~3)
 #endif
 
 /*
@@ -127,7 +127,7 @@
 MipsDoTLBMiss:
 	bltz		k0, 1f				#02: k0<0 -> 1f (kernel fault)
 	PTR_SRL		k0, k0, SEGSHIFT - PTRSHIFT	#03: k0=seg offset (almost)
-
+	
 	GET_CPU_PCPU(k1)
 	PTR_L		k1, PC_SEGBASE(k1)
 	beqz		k1, 2f				#05: make sure segbase is not null
@@ -146,7 +146,7 @@
 	beq		k1, zero, 2f			# ==0 -- no page table
 #endif
 	PTR_SRL		k0, PAGE_SHIFT - 2		#0b: k0=VPN (aka va>>10)
-	andi		k0, k0, 0xff8			#0c: k0=page tab offset
+	andi		k0, k0, TLB_PAGE_MASK & ~7	#0c: k0=page tab offset
 	PTR_ADDU	k1, k1, k0			#0d: k1=pte address
 	lw		k0, 0(k1)			#0e: k0=lo0 pte
 	lw		k1, 4(k1)			#0f: k1=lo0 pte
@@ -156,7 +156,11 @@
 	CLEAR_PTE_SWBITS(k1)
 	MTC0		k1, MIPS_COP_0_TLB_LO1		#15: lo1 is loaded
 	COP0_SYNC
+	li              k0, TLBMASK_MASK
+	MTC0		k0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
 	tlbwr						#1a: write to tlb
+	
 	HAZARD_DELAY
 	eret						#1f: retUrn from exception
 1:	j		MipsTLBMissException		#20: kernel exception
@@ -846,7 +850,7 @@
 #endif
 	MFC0		k0, MIPS_COP_0_BAD_VADDR	# k0=bad address (again)
 	PTR_SRL		k0, PAGE_SHIFT - 2		# k0=VPN
-	andi		k0, k0, 0xffc			# k0=page tab offset
+	andi		k0, k0, TLB_PAGE_MASK & ~3	# k0=page tab offset
 	PTR_ADDU	k1, k1, k0			# k1=pte address
 	lw		k0, 0(k1)			# k0=this PTE
 
@@ -868,6 +872,10 @@
 	CLEAR_PTE_SWBITS(k1)
 	MTC0		k1, MIPS_COP_0_TLB_LO1
 	COP0_SYNC
+	li              k0, TLB_PAGE_MASK
+	MTC0		k0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
+
 
 	b		tlb_insert_entry
 	nop
@@ -881,6 +889,9 @@
 	CLEAR_PTE_SWBITS(k1)
 	MTC0		k1, MIPS_COP_0_TLB_LO1
 	COP0_SYNC
+	li              k0, TLBMASK_MASK
+	MTC0		k0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
 
 tlb_insert_entry:
 	tlbp
@@ -890,12 +901,12 @@
 	nop
 	tlbwi
 	eret
-	ssnop
+	SSNOP
 
 tlb_insert_random:
 	tlbwr
 	eret
-	ssnop
+	SSNOP
 
 3:
 	/*
@@ -927,7 +938,8 @@
 	sll	k1, k1, PAGE_SHIFT + 1
 
 	PTR_LA	k0, _C_LABEL(pcpu_space)
-	PTR_ADDU	k0, PAGE_SIZE * 2
+	PTR_ADDU	k0, PAGE_SIZE
+	PTR_ADDU	k0, PAGE_SIZE
 	PTR_ADDU	k0, k0, k1
 
 	/*
@@ -1013,7 +1025,7 @@
   	beq		k1, zero, MipsKernGenException	# ==0 -- no page table
 #endif
 	PTR_SRL		k0, PAGE_SHIFT - 2		# k0=VPN
-	andi		k0, k0, 0xff8			# k0=page tab offset
+	andi		k0, k0, TLB_PAGE_MASK & ~7	# k0=page tab offset
 	PTR_ADDU	k1, k1, k0			# k1=pte address
 	lw		k0, 0(k1)			# k0=lo0 pte
 	lw		k1, 4(k1)			# k1=lo1 pte
@@ -1023,6 +1035,9 @@
 	CLEAR_PTE_SWBITS(k1)
 	MTC0		k1, MIPS_COP_0_TLB_LO1		# lo1 is loaded
 	COP0_SYNC
+	li              k0, TLBMASK_MASK
+	MTC0		k0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
 	tlbwr					# write to tlb
 	HAZARD_DELAY
 	eret					# return from exception

=== modified file 'mips/mips/swtch.S'
--- mips/mips/swtch.S	2010-08-13 22:16:49 +0000
+++ mips/mips/swtch.S	2010-08-17 04:01:47 +0000
@@ -308,6 +308,8 @@
 	MTC0	t1, MIPS_COP_0_TLB_HI
 	mtc0	zero, MIPS_COP_0_TLB_LO0
 	mtc0	zero, MIPS_COP_0_TLB_LO1
+	li              t1, TLBMASK_MASK
+	MTC0		t1, MIPS_COP_0_TLB_PG_MASK
 	HAZARD_DELAY
 	tlbwi
 	HAZARD_DELAY
@@ -320,6 +322,8 @@
 	mtc0	a1, MIPS_COP_0_TLB_LO0		# upte[0]
 	HAZARD_DELAY
 	mtc0	a2, MIPS_COP_0_TLB_LO1		# upte[1]
+	li              t1, TLBMASK_MASK
+	MTC0		t1, MIPS_COP_0_TLB_PG_MASK
 	HAZARD_DELAY
 	tlbwi					# set TLB entry #0
 	HAZARD_DELAY

=== modified file 'mips/mips/tlb.c'
--- mips/mips/tlb.c	2010-08-13 22:16:49 +0000
+++ mips/mips/tlb.c	2010-08-17 04:08:12 +0000
@@ -100,7 +100,7 @@
 	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
 
 	mips_wr_index(i);
-	mips_wr_pagemask(0);
+	mips_wr_pagemask(TLBMASK_MASK);
 	mips_wr_entryhi(TLBHI_ENTRY(va, 0));
 	mips_wr_entrylo0(pte0);
 	mips_wr_entrylo1(pte1);
@@ -122,7 +122,7 @@
 	s = intr_disable();
 	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
 
-	mips_wr_pagemask(0);
+	mips_wr_pagemask(TLBMASK_MASK);
 	mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap)));
 	tlb_probe();
 	i = mips_rd_index();
@@ -219,7 +219,7 @@
 	s = intr_disable();
 	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
 
-	mips_wr_pagemask(0);
+	mips_wr_pagemask(TLBMASK_MASK);
 	mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap)));
 	tlb_probe();
 	i = mips_rd_index();
@@ -245,7 +245,7 @@
 	mips_wr_entryhi(TLBHI_ENTRY(MIPS_KSEG0_START + (2 * i * PAGE_SIZE), 0));
 	mips_wr_entrylo0(0);
 	mips_wr_entrylo1(0);
-	mips_wr_pagemask(0);
+	mips_wr_pagemask(TLBMASK_MASK);
 	mips_wr_index(i);
 	tlb_write_indexed();
 }

=== modified file 'vm/vm_fault.c'
--- vm/vm_fault.c	2010-08-13 22:16:49 +0000
+++ vm/vm_fault.c	2010-08-17 16:40:21 +0000
@@ -979,6 +979,9 @@
 	vm_page_t m;
 	vm_object_t object;
 
+	if (PAGE_SIZE == 1 << 14)
+		return;
+
 	if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace))
 		return;
 


More information about the freebsd-mips mailing list