Merging 64 bit changes to -HEAD

Jayachandran C. c.jayachandran at gmail.com
Wed Jun 30 12:57:31 UTC 2010


On Tue, Jun 29, 2010 at 10:32 PM, Luiz Otavio O Souza
<lists.br at gmail.com> wrote:
>
> On Jun 29, 2010, at 8:02 AM, Jayachandran C. wrote:
>
>> On Tue, Jun 29, 2010 at 2:28 AM, Luiz Otavio O Souza <lists.br at gmail.com> wrote:
>>>> Thanks for the the update. Looks like pmap_map for kernel is failing,
>>>> may be the new tlb_update code causes this.  Can you apply the
>>>> attached patch and see if the problem still persists, it replaces the
>>>> new tlb_update code with the older version.
>>>>
>>>> Obviously not a fix, but if we can narrow it down to this function,
>>>> fixing will be easier.
>>>>
>>>> JC.
>>>> <try.diff>
>>>
>>> JC,
>>>
>>> This fix the problem ! Thanks ! Now, at least, you know where to look :)
>>
>> The new tlb_update does not seem to update the tlb entry if the tlbp
>> fails.  Here's a patch that should make the new function behave like
>> the older one.  The patch is in attached file 'tlb-update.diff'.
>>
>> If that does not work, I'm not sure what the issue is.  You could also
>> try try the nop-change.diff attached. It tries to switch the ssnop
>> used for delay in the new code with 'nop' which was used by the old
>> code.
>>
>> Thanks,
>> JC.
>> <tlb-update.diff><nop-change.diff>
>
> JC,
>
> The nop-change seems to have no effect at all and with the tlb-update patch the kernel apparently crash at bzero(), here is the dmesg with TRAP_DEBUG enabled:
>
> http://mips.pastebin.com/jydPvJ20
>
> So hopefully you are on the right track and this may be something obvious to you.

Not yet :) I really hoped the earlier change would fix it.  The number
of nop does not seem to be the issue as it is higher in the C code
than the assembly.

Can you try the attached patch (try.diff) - this re-implements the
assembly code functionality almost in the same way in C.  This really
should work, given that the patch which made it assembly worked...

If that works can you see if the second attached patch works, this
fixes a potential problem (ie, we should be masking 13bits for TLBHI).

Both patches should apply directly to SVN (not dependent on each
other, or on previous patches)

Thanks again,
JC.
-------------- next part --------------
Index: sys/mips/mips/tlb.c
===================================================================
--- sys/mips/mips/tlb.c	(revision 209521)
+++ sys/mips/mips/tlb.c	(working copy)
@@ -217,34 +217,43 @@
 void
 tlb_update(struct pmap *pmap, vm_offset_t va, pt_entry_t pte)
 {
-	register_t mask, asid;
-	register_t s;
-	int i;
+	pt_entry_t other;
+	register_t oldhi, hi, s;
+	int i, even;
 
-	va &= ~PAGE_MASK;
+	even = (va & PAGE_SIZE) == 0;
+	other = pte & PTE_G;
 	pte &= ~TLBLO_SWBITS_MASK;
+	hi = (va & 0xffffe000) | (pmap_asid(pmap) & 0xff);
 
 	s = intr_disable();
-	mask = mips_rd_pagemask();
-	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
-
-	mips_wr_pagemask(0);
-	mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap)));
+	oldhi = mips_rd_entryhi();
+	mips_wr_entryhi(hi);
 	tlb_probe();
 	i = mips_rd_index();
 	if (i >= 0) {
 		tlb_read();
 
-		if ((va & PAGE_SIZE) == 0) {
+		if (even) {
 			mips_wr_entrylo0(pte);
 		} else {
 			mips_wr_entrylo1(pte);
 		}
 		tlb_write_indexed();
+	} else {
+		mips_wr_pagemask(0);
+		mips_wr_entryhi(hi);
+		if (even) {
+			mips_wr_entrylo0(pte);
+			mips_wr_entrylo1(other);
+		} else {
+			mips_wr_entrylo0(other);
+			mips_wr_entrylo1(pte);
+		}
+		tlb_write_random();
 	}
 
-	mips_wr_entryhi(asid);
-	mips_wr_pagemask(mask);
+	mips_wr_entryhi(oldhi);
 	intr_restore(s);
 }
 
-------------- next part --------------
Index: sys/mips/include/pte.h
===================================================================
--- sys/mips/include/pte.h	(revision 209521)
+++ sys/mips/include/pte.h	(working copy)
@@ -73,7 +73,8 @@
  * Note that in FreeBSD, we map 2 TLB pages is equal to 1 VM page.
  */
 #define	TLBHI_ASID_MASK		(0xff)
-#define	TLBHI_ENTRY(va, asid)	(((va) & ~PAGE_MASK) | ((asid) & TLBHI_ASID_MASK))
+#define	TLBHI_PAGE_MASK		(~(2 * PAGE_SIZE - 1))
+#define	TLBHI_ENTRY(va, asid)	(((va) & TLBHI_PAGE_MASK) | ((asid) & TLBHI_ASID_MASK))
 
 #ifndef _LOCORE
 typedef	uint32_t pt_entry_t;


More information about the freebsd-mips mailing list