PERFORCE change 158254 for review

Arnar Mar Sig antab at FreeBSD.org
Wed Feb 25 04:21:27 PST 2009


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

Change 158254 by antab at antab_farm on 2009/02/25 12:20:26

	- Add kernel page tables to new pmap
	- Point PTBR to page directory instead of pmap so we can avoid having to touch memory that need tlb lookups while inside pmap_tlb_miss
	- Add driver for SMC, external memory devices get attached here.
	- Add cfi bus support for at32_smc and add hints to attach cfi to the onboard parallel flash
	- Add cfi patch from Sam Leffler
	- Add geom_hints slicer. Used to slice down the onboard flash using hints
	
	I'm now able to mount root on ufs filesystem from the onboard flash (cfid0h1) and getting ready to load init.

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/at32_smc.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/db_disasm.c#4 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#8 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#8 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/support.S#6 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#7 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#7 edit
.. //depot/projects/avr32/src/sys/avr32/conf/NGW100#7 edit
.. //depot/projects/avr32/src/sys/avr32/conf/NGW100.hints#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/pmap.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_smc.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/trap.h#3 edit
.. //depot/projects/avr32/src/sys/conf/files#3 edit
.. //depot/projects/avr32/src/sys/conf/files.avr32#6 edit
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_bus_at32_smc.c#1 add
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_bus_lbc.c#2 edit
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_core.c#2 edit
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_dev.c#2 edit
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_reg.h#2 edit
.. //depot/projects/avr32/src/sys/dev/cfi/cfi_var.h#2 edit
.. //depot/projects/avr32/src/sys/geom/geom_hints.c#1 add

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/db_disasm.c#4 (text+ko) ====

@@ -439,7 +439,7 @@
 		}
 		walker++;
 	}
-	db_printf("UNKNOWN");
+	db_printf("UNKNOWN\n");
 	return (loc + 2);
 
 found:
@@ -451,6 +451,7 @@
 	if (walker->operand != NULL) {
 		walker->operand(inst, walker->operand_arg);
 	}
+	db_printf("\n");
 	return (loc + walker->size);
 }
 

==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#8 (text+ko) ====


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

@@ -103,7 +103,7 @@
 
 	/* Enable paging */
 	tlb_flush();
-	sysreg_write(PTBR, (uint32_t)kernel_pmap);
+	sysreg_write(PTBR, (uint32_t)kernel_pmap->pm_pd);
 	sysreg_write(MMUCR,
 	    bit_offset(SYS, MMUCR, S) |
 	    bit_offset(SYS, MMUCR, E) |
@@ -166,6 +166,7 @@
 {
 	vm_page_t ptdpg;
 	PMAP_LOCK_INIT(pmap);
+	int i;
 
 	/* allocate the page directory page */
 	ptdpg = vm_page_alloc(NULL, 512,
@@ -177,6 +178,12 @@
 		bzero(pmap->pm_pd, PAGE_SIZE);
 	}
 
+	/* Add kernel page tables */
+	for (i = (virtual_avail >> PD_SHIFT); i < (virtual_end >> PD_SHIFT);
+		i++) {
+		pmap->pm_pd[i] = kernel_pmap->pm_pd[i];
+	}
+
 	pmap->pm_active = 0;
 	pmap->pm_asid = 0;
 	pmap->pm_asid_generation = 0;
@@ -209,7 +216,11 @@
 void
 pmap_clear_modify(vm_page_t m)
 {
-	avr32_impl();
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	if (m->md.pv_flags & PV_TABLE_MOD) {
+		//pmap_changebit(m, PTE_M, FALSE);	TODO
+		m->md.pv_flags &= ~PV_TABLE_MOD;
+	}
 }
 
 int
@@ -495,7 +506,7 @@
 			if (origpte & PTE_DIRTY) {
 				KASSERT((origpte & PTE_RW),
 					("pmap_enter: modified page not writable:"
-					" va: 0x%x, pte: 0x%lx", va, origpte));
+					" va: 0x%x, pte: 0x%x", va, origpte));
 				if (page_is_managed(opa)) {
 					vm_page_dirty(om);
 				}
@@ -548,7 +559,32 @@
 void
 pmap_remove_all(vm_page_t m)
 {
-	avr32_impl();
+	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--;
+
+		pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+		// TODO More work needed
+
+		TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+		m->md.pv_list_count--;
+		PMAP_UNLOCK(pv->pv_pmap);
+		free_pv_entry(pv);
+	}
+
+	vm_page_flag_clear(m, PG_WRITEABLE);
+	m->md.pv_flags &= ~(PV_TABLE_REF | PV_TABLE_MOD);
 }
 
 void
@@ -560,7 +596,29 @@
 void
 pmap_remove_write(vm_page_t m)
 {
-	avr32_impl();
+	pv_entry_t pv, npv;
+	vm_offset_t va;
+	pt_entry_t *pte;
+
+	if ((m->flags & PG_WRITEABLE) == 0)
+	return;
+
+	/*
+	 * Loop over all current mappings setting/clearing as appropos.
+	 */
+	for (pv = TAILQ_FIRST(&m->md.pv_list); pv; pv = npv) {
+		npv = TAILQ_NEXT(pv, pv_plist);
+		pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+
+		if (pte == NULL) {
+			panic("page on pm_pvlist has no pte\n");
+		}
+
+		va = pv->pv_va;
+		pmap_protect(pv->pv_pmap, va, va + PAGE_SIZE,
+			VM_PROT_READ | VM_PROT_EXECUTE);
+	}
+	vm_page_flag_clear(m, PG_WRITEABLE);
 }
 
 vm_paddr_t
@@ -815,25 +873,52 @@
 	}
 }
 
+void
+pmap_dump(pmap_t pmap)
+{
+	pt_entry_t *base, *ent;
+	int i, p;
+
+	for (i = 0; i < 1024; i++) {
+		base = (pt_entry_t *)pmap->pm_pd[i];
+		if (!base || !*base) {
+			continue;
+		}
+
+		for (p = 0; p < 1024; p++) {
+			ent = base + p;
+			if (*ent) {
+				printf("0x%x -> 0x%x\n",
+					(i << PD_SHIFT) | (p << PT_SHIFT),
+					*ent);
+			}
+		}
+	}
+}
+
 /**
  * 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) {
-	pmap_t pmap = (pmap_t)sysreg_read(PTBR);
+	pd_entry_t* pd = (pd_entry_t *)sysreg_read(PTBR);
 	pt_entry_t *ent;
 	register_t mmucr;
 
-	ent = pmap_pte(pmap, tlbear);
+	ent = (pt_entry_t *)pd[pd_index_from_va(tlbear)];
+	if (ent) {
+		ent += pt_index_from_va(tlbear);
+	}
+
 	if (!ent || !*ent) {
-		breakpoint();
-	/*	printf("\nTLB miss: %x\n", ecr);
+/*		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)); */
-		panic("pmap_tlb_miss: address not in pmap\n");
+		breakpoint();
+		panic("pmap_tlb_miss: address 0x%x not in pd %p\n", tlbear, pd);
 	}
 
 	mmucr = sysreg_read(MMUCR);

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

@@ -208,7 +208,6 @@
  */
 ENTRY(fubyte)
 ENTRY(fuword)
-ENTRY(fuword16)
 ENTRY(fuword32)
 ENTRY(fuword64)
 	breakpoint
@@ -218,11 +217,21 @@
  * All these functions are MPSAFE.
  */
 ENTRY(subyte)
+	breakpoint
+	st.b	r12, r11
+	retal	sp
+END(subyte)
+
 ENTRY(suword)
-ENTRY(suword16)
 ENTRY(suword32)
+	breakpoint
+	st.w	r12, r11
+	retal	sp
+END(suword)
+
 ENTRY(suword64)
 	breakpoint
+END(suword64)
 
 /*
  * fuswintr and suswintr are just like fusword and susword except that if
@@ -243,9 +252,7 @@
  */
 ENTRY(casuword32)
 ENTRY(casuword)
-	sub	r12, pc, (. - casuword_need)
-	bral    panic
-casuword_need: .asciz "casuword needed"
+	breakpoint
 END(casuword)
 
 

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

@@ -88,6 +88,7 @@
 	ld.w	r4, r11[PMAP_ASID]
 	add	r10, r4
 	sbr	r10, AT32_SYS_TLBEHI_V
+	ld.w	r11, r11[PMAP_PD]		/* Point r11 to page directory */
 
 	sub	r9, r12, -(TD_KPTE)		/* Add KPTE offset to thread struct pointer */
 	mov	r8, KSTACK_PAGES		/* Iterate thru thru all kstack pages */

==== //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#7 (text+ko) ====

@@ -161,11 +161,11 @@
 	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
 
 	/* Sets regs (need to look into this better later on) */
-	td->td_pcb->pcb_regs.regs.r10 = (register_t)fork_return;
+	td->td_pcb->pcb_regs.regs.r9 = (register_t)fork_return;
 	td->td_pcb->pcb_regs.regs.r11 = (register_t)td;
-	td->td_pcb->pcb_regs.regs.r12 = (register_t)td->td_frame;
+	td->td_pcb->pcb_regs.regs.r10 = (register_t)td->td_frame;
 	td->td_pcb->pcb_regs.regs.sp = (register_t)td->td_frame - sizeof(void *);
-	td->td_pcb->pcb_regs.regs.pc = (register_t)fork_trampoline;
+	td->td_pcb->pcb_regs.regs.lr = (register_t)fork_trampoline;
 
 	td->td_md.md_saved_intr = 0;		/* TODO: probably not right. */
 	td->td_md.md_spinlock_count = 1;
@@ -217,9 +217,9 @@
 		pmap = vmspace_pmap(new->td_proc->p_vmspace);
 		pmap_activate(new);
 
-		printf("New thread %p, pmap: %p, pcb: %p, stack: 0x%x - 0x%x\n", new,
-			pmap, new->td_pcb, new->td_kstack,
-			new->td_kstack + (KSTACK_PAGES * PAGE_SIZE) - 1);
+/*		printf("New thread %p, pmap: %p, stack: 0x%x - 0x%x\n", new,
+			pmap, new->td_kstack,
+			new->td_kstack + (KSTACK_PAGES * PAGE_SIZE) - 1); */
 
 		restorectx(new, pmap);
 

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

@@ -21,6 +21,11 @@
 options		NFSCLIENT		#Network Filesystem Client
 options		NFS_ROOT		#NFS usable as /, requires NFSCLIENT
 options		PSEUDOFS		#Pseudo-filesystem framework
+options		FFS			# Berkeley Fast Filesystem
+options		SOFTUPDATES		# Enable FFS soft updates support
+options		UFS_ACL			# Support for access control lists
+options		UFS_DIRHASH		# Improve performance on big directories
+options		UFS_GJOURNAL		# Enable gjournal-based UFS journaling
 options		SYSVSHM			#SYSV-style shared memory
 options		SYSVMSG			#SYSV-style message queues
 options		SYSVSEM			#SYSV-style semaphores
@@ -36,6 +41,7 @@
 
 device		at32_intc		# Interrupt controller
 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
@@ -46,6 +52,11 @@
 #device		atmel_ssc		# Sync Serial controller
 #device		atmel_mci		# Media card interface
 
+# Drivers for onboard parallel flash
+device		cfi
+device		cfid
+device		geom_hints
+
 # Pseudo devices.
 device		loop
 device		random

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

@@ -1,3 +1,33 @@
 # Device wiring for Atmel ngw100
 #
 # $FreeBSD: $
+
+# Onboard parallel cfi
+hint.cfi.0.at="at32_smc"
+hint.cfi.0.maddr="0x00000000"
+hint.cfi.0.msize="0x007FFFFF"
+hint.cfi.0.bus_width="2"
+hint.cfi.0.nrd_controlled="1"
+hint.cfi.0.nwe_controlled="1"
+hint.cfi.0.byte_write="1"
+# All timings are in nano sec
+hint.cfi.0.ncs_read_setup="0"
+hint.cfi.0.nrd_setup="40"
+hint.cfi.0.ncs_write_setup="0"
+hint.cfi.0.nwe_setup="10"
+hint.cfi.0.ncs_read_pulse="80"
+hint.cfi.0.nrd_pulse="40"
+hint.cfi.0.ncs_write_pulse="65"
+hint.cfi.0.nwe_pulse="55"
+hint.cfi.0.read_cycle="120"
+hint.cfi.0.write_cycle="120"
+# geom_hints for flash
+hint.geom_hints.0.at="cfid0"
+hint.geom_hints.0.maddr="0x00000000"
+hint.geom_hints.0.msize="0x00020000"
+hint.geom_hints.1.at="cfid0"
+hint.geom_hints.1.maddr="0x00020000"
+hint.geom_hints.1.msize="0x007d0000"
+hint.geom_hints.2.at="cfid0"
+hint.geom_hints.2.maddr="0x007f0000"
+hint.geom_hints.2.msize="0x00010000"

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

@@ -189,6 +189,7 @@
 void pmap_unmapdev(vm_offset_t, vm_size_t);
 void pmap_deactivate(struct thread *);
 void pmap_asid_alloc(pmap_t pmap);
+void pmap_dump(pmap_t);
 
 /**
  * Get page table entry from virtual address in a given pmap

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

@@ -36,7 +36,7 @@
 void trap_handle_address_fault(uint32_t ecr, struct trapframe *reg);
 void trap_handle_protection_fault(uint32_t ecr, struct trapframe *reg);
 void trap_handle_dtlb_modified(uint32_t ecr, struct trapframe *reg);
-
+void trapframe_dump(struct trapframe *frame);
 
 #define T_BREAKPOINT		0x07
 

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

@@ -701,6 +701,7 @@
 dev/cardbus/cardbus_device.c	optional cardbus
 dev/cfi/cfi_core.c		optional cfi
 dev/cfi/cfi_dev.c		optional cfi
+dev/cfi/cfi_disk.c		optional cfid
 dev/ciss/ciss.c			optional ciss
 dev/cm/smc90cx6.c		optional cm
 dev/cmx/cmx.c			optional cmx
@@ -1816,6 +1817,7 @@
 geom/geom_mbr_enc.c		optional geom_mbr
 geom/geom_pc98.c		optional geom_pc98
 geom/geom_pc98_enc.c		optional geom_pc98
+geom/geom_hints.c		optional geom_hints
 geom/geom_slice.c		standard
 geom/geom_subr.c		standard
 geom/geom_sunlabel.c		optional geom_sunlabel

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

@@ -31,6 +31,8 @@
 avr32/avr32/at32_rtc.c		optional	at32_rtc
 avr32/avr32/at32_pio.c		optional	at32_pio
 avr32/avr32/at32_sdramc.c	optional	at32_sdramc
+avr32/avr32/at32_smc.c		optional	at32_smc
+dev/cfi/cfi_bus_at32_smc.c	optional	at32_smc cfi
 
 libkern/ashldi3.c		standard
 libkern/ashrdi3.c		standard

==== //depot/projects/avr32/src/sys/dev/cfi/cfi_bus_lbc.c#2 (text+ko) ====


==== //depot/projects/avr32/src/sys/dev/cfi/cfi_core.c#2 (text+ko) ====

@@ -49,6 +49,7 @@
 
 char cfi_driver_name[] = "cfi";
 devclass_t cfi_devclass;
+devclass_t cfi_diskclass;
 
 uint32_t
 cfi_read(struct cfi_softc *sc, u_int ofs)
@@ -278,6 +279,10 @@
 	    "%s%u", cfi_driver_name, u);
 	sc->sc_nod->si_drv1 = sc;
 
+	device_add_child(dev, "cfid",
+	    devclass_find_free_unit(cfi_diskclass, 0));
+	bus_generic_attach(dev);
+
 	return (0);
 }
 

==== //depot/projects/avr32/src/sys/dev/cfi/cfi_dev.c#2 (text+ko) ====

@@ -72,7 +72,7 @@
  * or the process stops writing. At that time we write the whole
  * sector to flash (see cfi_block_finish).
  */
-static int
+int
 cfi_block_start(struct cfi_softc *sc, u_int ofs)
 {
 	union {
@@ -122,7 +122,7 @@
  * Finish updating the current block/sector by writing the compound
  * set of changes to the flash.
  */
-static int
+int
 cfi_block_finish(struct cfi_softc *sc)
 {
 	int error;

==== //depot/projects/avr32/src/sys/dev/cfi/cfi_reg.h#2 (text+ko) ====


==== //depot/projects/avr32/src/sys/dev/cfi/cfi_var.h#2 (text+ko) ====

@@ -65,6 +65,7 @@
 
 extern char cfi_driver_name[];
 extern devclass_t cfi_devclass;
+extern devclass_t cfi_diskclass;
 
 int cfi_probe(device_t);
 int cfi_attach(device_t);
@@ -73,5 +74,7 @@
 uint32_t cfi_read(struct cfi_softc *, u_int);
 uint8_t cfi_read_qry(struct cfi_softc *, u_int);
 int cfi_write_block(struct cfi_softc *);
+int cfi_block_start(struct cfi_softc *, u_int);
+int cfi_block_finish(struct cfi_softc *);
 
 #endif /* _DEV_CFI_VAR_H_ */


More information about the p4-projects mailing list