PERFORCE change 158473 for review

Arnar Mar Sig antab at FreeBSD.org
Sat Feb 28 10:49:04 PST 2009


http://perforce.freebsd.org/chv.cgi?CH=158473

Change 158473 by antab at antab_farm on 2009/02/28 18:48:26

	- Move if_ate from arm/at91/ to dev/ate/ and make it build and attach on at32, fails on busdma for now.
	- Add at32_hmatrix, only for dumping the hmatrix setup for now, later provide access to change bus setup from userspace.
	- Continue implmenting pmap_tlb_miss to call vm_fault, can now page in on demand.
	- Other bits needed to load init. Able to find, load and fail executing dumb init.

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/exception.S#6 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#10 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/support.S#7 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#6 edit
.. //depot/projects/avr32/src/sys/avr32/conf/NGW100#10 edit
.. //depot/projects/avr32/src/sys/avr32/conf/cpu/at32ap7000.hints#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/pmap.h#4 edit
.. //depot/projects/avr32/src/sys/avr32/include/pte.h#4 edit
.. //depot/projects/avr32/src/sys/avr32/include/trap.h#4 edit
.. //depot/projects/avr32/src/sys/conf/files#5 edit
.. //depot/projects/avr32/src/sys/conf/files.avr32#10 edit
.. //depot/projects/avr32/src/sys/dev/ate/if_ate.c#1 add

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/exception.S#6 (text+ko) ====

@@ -134,6 +134,7 @@
 	mfsr    r12, AT32_SYS_ECR
 	mfsr    r11, AT32_SYS_TLBEAR
 	mfsr    r10, AT32_SYS_TLBEHI
+	mov	r9, sp
 	rcall   pmap_tlb_miss
 	POP_TRAPFRAME(EX)
 	rete

==== //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#10 (text+ko) ====

@@ -30,6 +30,7 @@
 #include <machine/tlb.h>
 #include <machine/reg.h>
 #include <machine/reg_sys.h>
+#include <machine/trap.h>
 #include <machine/debug.h>
 
 // antab: What does this stand for?
@@ -44,6 +45,8 @@
 static void pmap_remove_entry(struct pmap *pmap, vm_page_t m, vm_offset_t va);
 static void free_pv_entry(pv_entry_t pv);
 static pv_entry_t get_pv_entry(void);
+static int pmap_remove_pte(struct pmap *pmap, pt_entry_t *ptq, vm_offset_t va);
+static void pmap_remove_page(struct pmap *pmap, vm_offset_t va);
 
 
 static struct pmap kernel_pmap_store;
@@ -88,6 +91,7 @@
 	kernel_pmap->pm_active = ~0;
 	kernel_pmap->pm_asid = 0;
 	kernel_pmap->pm_asid_generation = 0;
+	TAILQ_INIT(&kernel_pmap->pm_pvlist);
 
 	/* Setup kernel page dir and table */
 	kernel_pmap->pm_pd = (pd_entry_t *)pmap_steal_memory(PAGE_SIZE);
@@ -254,7 +258,7 @@
 	if (!ent) {
 		panic("pmap_kenter: not in kernel segment\n");
 	}
-	*ent = PTE_CACHEABLE | PTE_PERM_READ | PTE_PERM_WRITE;
+	*ent = PTE_CACHEABLE | PTE_PERM_READ | PTE_PERM_WRITE | PTE_GLOBAL;
 	pfn_set(*ent, pa);
 
 	/* No need to do any tlb inserts, will just get a miss exception
@@ -439,7 +443,7 @@
 		 * We might be turning off write access to the page, so we
 		 * go ahead and sense modify status.
 		 */
-        if (page_is_managed(opa)) {
+		if (page_is_managed(opa)) {
 			om = m;
 		}
 		goto update;
@@ -553,7 +557,39 @@
 void
 pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
 {
-	avr32_impl();
+	vm_offset_t va;
+	pt_entry_t *pte;
+
+	if (pmap == NULL) {
+		return;
+	}
+
+	if (pmap->pm_stats.resident_count == 0) {
+		return;
+	}
+
+	vm_page_lock_queues();
+	PMAP_LOCK(pmap);
+
+	/*
+	 * special handling of removing one page.  a very common operation
+	 * and easy to short circuit some code.
+	 */
+	if ((sva + PAGE_SIZE) == eva) {
+		pmap_remove_page(pmap, sva);
+		goto out;
+	}
+	for (va = sva; va < eva; va += PAGE_SIZE) {
+		pte = pmap_pte(pmap, va);
+		if (!pte || !*pte) {
+			continue;
+		}
+		pmap_remove_page(pmap, va);
+	}
+
+out:
+	vm_page_unlock_queues();
+	PMAP_UNLOCK(pmap);
 }
 
 void
@@ -562,19 +598,28 @@
 	register pv_entry_t pv;
 	register pt_entry_t *pte;
 
-
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	if (m->md.pv_flags & PV_TABLE_REF) {
 		vm_page_flag_set(m, PG_REFERENCED);
 	}
 
 	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
-		printf("Remove from pmap: %p\n", pv->pv_pmap);
 		PMAP_LOCK(pv->pv_pmap);
 		pv->pv_pmap->pm_stats.resident_count--;
 
+
+		/*
+		 * Update the vm_page_t clean and reference bits.
+		 */
 		pte = pmap_pte(pv->pv_pmap, pv->pv_va);
-		// TODO More work needed
+		if (*pte & PTE_WIRED) {
+                        pv->pv_pmap->pm_stats.wired_count--;
+		}
+		//if (*pte & PTE_M) {
+		//	vm_page_dirty(m);
+		//} TODO
+		*pte = 0;
+		tlb_remove_entry(pv->pv_pmap, pv->pv_va);
 
 		TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
 		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
@@ -621,6 +666,70 @@
 	vm_page_flag_clear(m, PG_WRITEABLE);
 }
 
+/*
+ * pmap_remove_pte: do the things to unmap a page in a process
+ */
+static int
+pmap_remove_pte(struct pmap *pmap, pt_entry_t *ptq, vm_offset_t va)
+{
+	vm_page_t m;
+	vm_offset_t pa;
+
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+
+	if (*ptq & PTE_WIRED) {
+		pmap->pm_stats.wired_count--;
+	}
+
+	pmap->pm_stats.resident_count--;
+	pa = pfn_get(*ptq);
+
+	if (page_is_managed(pa)) {
+		m = PHYS_TO_VM_PAGE(pa);
+		//if (oldpte & PTE_M) {
+		//	vm_page_dirty(m);
+		//} TODO
+		if (m->md.pv_flags & PV_TABLE_REF) {
+			vm_page_flag_set(m, PG_REFERENCED);
+		}
+		m->md.pv_flags &= ~(PV_TABLE_REF | PV_TABLE_MOD);
+
+		if (pmap_page_is_mapped(m)) {
+			pmap_remove_entry(pmap, m, va);
+		}
+	}
+	*ptq = 0;
+	return (1);
+}
+
+/*
+ * Remove a single page from a process address space
+ */
+static void
+pmap_remove_page(struct pmap *pmap, vm_offset_t va)
+{
+	register pt_entry_t *pte;
+
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	pte = pmap_pte(pmap, va);
+
+	/*
+	 * if there is no pte for this address, just skip it!!!
+	 */
+	if (!pte || !*pte) {
+		return;
+	}
+	/*
+	 * get a local va for mappings for this pmap.
+	 */
+	pmap_remove_pte(pmap, pte, va);
+	tlb_remove_entry(pmap, va);
+
+	return;
+}
+
 vm_paddr_t
 pmap_extract(pmap_t pmap, vm_offset_t va)
 {
@@ -746,9 +855,8 @@
 	 * isn't already there.
 	 */
 	pmap->pm_stats.resident_count++;
-	ptepa = VM_PAGE_TO_PHYS(m);
+	ptepa = AVR32_PHYS_TO_P1(VM_PAGE_TO_PHYS(m));
 	pmap->pm_pd[ptepindex] = (pd_entry_t)ptepa;
-	avr32_impl();
 	return m;
 }
 
@@ -793,7 +901,6 @@
 	boolean_t wired)
 {
 	pv_entry_t pv;
-
 	pv = get_pv_entry();
 	if (pv == NULL) {
 		panic("no pv entries: increase vm.pmap.shpgperproc");
@@ -819,13 +926,13 @@
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
 		TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
-		if (pmap == pv->pv_pmap && va == pv->pv_va)
-			break;
+			if (pmap == pv->pv_pmap && va == pv->pv_va)
+				break;
 		}
 	} else {
 		TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
-		if (va == pv->pv_va)
-			break;
+			if (va == pv->pv_va)
+				break;
 		}
 	}
 
@@ -906,7 +1013,7 @@
  * Called when we need to update the TLB
  */
 static int tlb_at = KSTACK_PAGES;
-void pmap_tlb_miss(uint32_t ecr, uint32_t tlbear, uint32_t tlbehi) {
+void pmap_tlb_miss(uint32_t ecr, uint32_t tlbear, uint32_t tlbehi, struct trapframe *tf) {
 	pd_entry_t* pd = (pd_entry_t *)sysreg_read(PTBR);
 	pt_entry_t *ent;
 	register_t mmucr;
@@ -917,12 +1024,82 @@
 	}
 
 	if (!ent || !*ent) {
+		/*
+		 * Enable exceptions before continuing, we are going to
+		 * hit memory needs tlb lookups from here one.
+		 */
+		__asm__ __volatile__ ("csrf %0" : : "i"(AT32_SYS_SR_EM));
+		__asm__ __volatile__ ("csrf %0" : : "i"(AT32_SYS_SR_GM));
+
+		if (tlbear == 0x0) {
+			panic("Access to 0x0! OMG!\n");
+		}
+		struct thread *td = curthread;
+		struct proc *p = curproc;
+		vm_prot_t ftype;
+		vm_map_t map;
+		vm_offset_t va;
+		int rv = 0;
+		ksiginfo_t ksi;
+
+		ftype = (ecr == T_TLB_MISS_WRITE) ? VM_PROT_WRITE : VM_PROT_READ;
+		va = trunc_page((vm_offset_t)tlbear);
+
+		if ((vm_offset_t)tlbear < VM_MIN_KERNEL_ADDRESS) {
+			map = &p->p_vmspace->vm_map;
+
+			/*
+			 * Keep swapout from messing with us during this
+			 * critical time.
+			 */
+			PROC_LOCK(p);
+			++p->p_lock;
+			PROC_UNLOCK(p);
+
+			rv = vm_fault(map, va, ftype,
+				(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
+							: VM_FAULT_NORMAL);
+
+			PROC_LOCK(p);
+			--p->p_lock;
+			PROC_UNLOCK(p);
+		} else {
+			map = kernel_map;
+
+			rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
+		}
+
+		if (rv == KERN_SUCCESS) {
+			if (!TRAPF_USERMODE(tf)) {
+				return;
+			}
+			goto out;
+		}
+		if (!TRAPF_USERMODE(tf)) {
+			panic("Fault in kernel at 0x%x", tlbear);
+		}
+
+		/*
+		 * Generate signal
+		 */
+		td->td_frame->regs.pc = tf->regs.pc;
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
+		ksi.ksi_code = ftype;
+		ksi.ksi_addr = (void *)tf->regs.pc;
+		ksi.ksi_trapno = ecr;
+		trapsignal(td, &ksi);
+out:
+		userret(td, tf);
+		return;
+
 /*		printf("\nTLB miss: %x\n", ecr);
 		printf("pd: %x\n", sysreg_read(PTBR));
 		printf("TLBEAR: %x\n", tlbear);
 		printf("TLBEHI: %x\n", tlbehi);
 		printf("PC: %x\n", sysreg_read(RAR_EX));
 		printf("SR: %x\n", sysreg_read(RSR_EX)); */
+
 		breakpoint();
 		panic("pmap_tlb_miss: address 0x%x not in pd %p\n", tlbear, pd);
 	}

==== //depot/projects/avr32/src/sys/avr32/avr32/support.S#7 (text+ko) ====

@@ -140,20 +140,6 @@
 END(copyout)
 
 /**
- * Copy a null terminated string from the user address space into
- * the kernel address space.
- *
- *      copyinstr(fromaddr, toaddr, maxlength, &lencopied)
- *              caddr_t fromaddr;
- *              caddr_t toaddr;
- *              u_int maxlength;
- *              u_int *lencopied;
- */
-ENTRY(copyinstr)
-	breakpoint
-END(copyinstr)
-
-/**
  * Copy a null terminated string from the kernel address space into
  * the user address space.
  *
@@ -178,6 +164,8 @@
  * r9   lencopied(pushed)/char
  * r8	copy count
  */
+ENTRY(copyinstr)
+	/* TODO: Should probably check addresses.. */
 ENTRY(copystr)
 	st.w	--sp, r9		/* Push r9 to stack */
 	mov	r8, 0			/* Clear copy count */
@@ -207,24 +195,31 @@
  * memory.  All these functions are MPSAFE.
  */
 ENTRY(fubyte)
+	ld.ub	r12, r12
+	retal	r12
+END(fubyte)
+
 ENTRY(fuword)
 ENTRY(fuword32)
+	ld.w	r12, r12
+	retal	r12
+END(fuword32)
+
 ENTRY(fuword64)
 	breakpoint
+END(fuword64)
 
 /*
  * Store a 32-bit word, a 16-bit word, or an 8-bit byte to user memory.
  * All these functions are MPSAFE.
  */
 ENTRY(subyte)
-	breakpoint
 	st.b	r12, r11
 	retal	sp
 END(subyte)
 
 ENTRY(suword)
 ENTRY(suword32)
-	breakpoint
 	st.w	r12, r11
 	retal	sp
 END(suword)

==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#6 (text+ko) ====


==== //depot/projects/avr32/src/sys/avr32/conf/NGW100#10 (text+ko) ====

@@ -9,6 +9,7 @@
 hints		"cpu/at32ap700x.hints"	# Hints for all buildin devices
 hints		"cpu/at32ap7000.hints"	# Hints for all buildin devices
 hints		"NGW100.hints"
+options		ROOTDEVNAME=\"ufs:cfid0h1\"
 
 makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
 #options		VERBOSE_SYSINIT
@@ -40,11 +41,15 @@
 #options	WITNESS_KDB
 
 device		at32_intc		# Interrupt controller
+device		at32_hmatrix		# HSB Bus Matrix
 device		at32_sdramc		# SDRAM controller
 device		at32_smc		# Static memory controller
 device		at32_pm			# Power Manager
 device		at32_rtc		# Real Time Counter (System clock)
 device		at32_pio		# Peripheral IO
+#device		mii			# Requred for ate
+#device		ate			# MACB Ethernet driver
+
 #device		gpio			# GPIO framework
 device		uart			# USART support
 #device		atmel_twi		# TWI (I2C) support

==== //depot/projects/avr32/src/sys/avr32/conf/cpu/at32ap7000.hints#2 (text+ko) ====

@@ -6,12 +6,12 @@
 hint.at32_lcdc.0.msize="0x200000"
 hint.at32_lcdc.0.irq="1"
 
-hint.at32_macb.0.at="at32bus0"
-hint.at32_macb.0.maddr="0xFFF01800"
-hint.at32_macb.0.msize="0x400"
-hint.at32_macb.0.irq="25"
+hint.ate.0.at="at32bus0"
+hint.ate.0.maddr="0xFFF01800"
+hint.ate.0.msize="0x400"
+hint.ate.0.irq="25"
 
-hint.at32_macb.1.at="at32bus0"
-hint.at32_macb.1.maddr="0xFFF01C00"
-hint.at32_macb.1.msize="0x400"
-hint.at32_macb.1.irq="26"
+hint.ate.1.at="at32bus0"
+hint.ate.1.maddr="0xFFF01C00"
+hint.ate.1.msize="0x400"
+hint.ate.1.irq="26"

==== //depot/projects/avr32/src/sys/avr32/include/pmap.h#4 (text+ko) ====

@@ -106,6 +106,7 @@
 
 #include <sys/queue.h>
 #include <machine/pte.h>
+#include <machine/trap.h>
 
 #define NKPT		128 /* actual number of kernel page tables */
 
@@ -196,7 +197,7 @@
  */
 pt_entry_t* pmap_pte(pmap_t pmap, vm_offset_t va);
 
-void pmap_tlb_miss(uint32_t ecr, uint32_t tlbear, uint32_t tlbehi);
+void pmap_tlb_miss(uint32_t ecr, uint32_t tlbear, uint32_t tlbehi, struct trapframe *);
 
 #define	pmap_resident_count(pm)	((pm)->pm_stats.resident_count)
 #define	vtophys(va)	pmap_kextract((vm_offset_t)(va))

==== //depot/projects/avr32/src/sys/avr32/include/pte.h#4 (text+ko) ====

@@ -42,12 +42,13 @@
 #define PD_SHIFT		22
 #define PT_SHIFT		12
 
-#define PTE_WIRED		1 << bit_shift(SYS, TLBELO, SZ)	/* Reuse size field */
+#define PTE_SOFTWARE_MASK	bit_mask(SYS, TLBELO, SZ)	/* Mask bits used by software */
 #define PTE_WRITE_THRU		bit_offset(SYS, TLBELO, W)	/* Write thru */
 #define PTE_PERM_READ		4 << bit_shift(SYS, TLBELO, AP)
 #define PTE_PERM_WRITE		2 << bit_shift(SYS, TLBELO, AP)
 #define PTE_PERM_EXECUTE	1 << bit_shift(SYS, TLBELO, AP)
 #define PTE_WIRED		1 << bit_shift(SYS, TLBELO, SZ)	/* Reuse size field for wired */
+#define PTE_GLOBAL		bit_offset(SYS, TLBELO, G)
 #define PTE_BUFFERABLE		bit_offset(SYS, TLBELO, B)	/* Bufferable */
 #define PTE_CACHEABLE		bit_offset(SYS, TLBELO,	C)	/* Cacheable */
 #define PTE_DIRTY		bit_offset(SYS, TLBELO, D)	/* Dirty */

==== //depot/projects/avr32/src/sys/avr32/include/trap.h#4 (text+ko) ====

@@ -39,5 +39,10 @@
 void trapframe_dump(struct trapframe *frame);
 
 #define T_BREAKPOINT		0x07
+#define T_TLB_PROT_READ		0x0F
+#define T_TLB_PROT_WRITE	0x10
+#define T_TLB_MISS_READ		0x18
+#define T_TLB_MISS_WRITE	0x1C
+
 
 #endif /* _MACHINE_TRAP_H_ */

==== //depot/projects/avr32/src/sys/conf/files#5 (text+ko) ====

@@ -509,6 +509,7 @@
 dev/ata/atapi-tape.c		optional atapist
 dev/ata/atapi-cam.c		optional atapicam
 #
+dev/ate/if_ate.c		optional ate
 dev/ath/if_ath.c		optional ath \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/if_ath_pci.c		optional ath pci \

==== //depot/projects/avr32/src/sys/conf/files.avr32#10 (text+ko) ====

@@ -12,6 +12,7 @@
 avr32/avr32/pm_machdep.c	standard
 avr32/avr32/elf_machdep.c	standard
 avr32/avr32/uio_machdep.c	standard
+avr32/avr32/busdma_machdep.c	standard
 avr32/avr32/sf_buf.c		standard
 avr32/avr32/cache.c		standard
 avr32/avr32/clock.c		standard
@@ -29,6 +30,7 @@
 
 avr32/avr32/at32_intc.c		optional	at32_intc
 avr32/avr32/at32_pm.c		optional	at32_pm
+avr32/avr32/at32_hmatrix.c	optional	at32_hmatrix
 avr32/avr32/at32_rtc.c		optional	at32_rtc
 avr32/avr32/at32_pio.c		optional	at32_pio
 avr32/avr32/at32_sdramc.c	optional	at32_sdramc
@@ -39,17 +41,17 @@
 
 libkern/ashldi3.c		standard
 libkern/ashrdi3.c		standard
-libkern/avr32/muldi64.c		standard
-libkern/divdi3.c		standard
+#libkern/avr32/muldi64.c		standard
+#libkern/divdi3.c		standard
 libkern/ffs.c			standard
 libkern/ffsl.c			standard
 libkern/fls.c			standard
 libkern/flsl.c			standard
 #libkern/lshrdi3.c		standard
-libkern/moddi3.c		standard
+#libkern/moddi3.c		standard
 libkern/qdivrem.c		standard
-libkern/udivdi3.c		standard
-libkern/umoddi3.c		standard
+#libkern/udivdi3.c		standard
+#libkern/umoddi3.c		standard
 
 avr32/avr32/in_cksum.c		optional	inet
 


More information about the p4-projects mailing list