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