[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