Date: Sat, 28 Feb 2009 18:49:02 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 158473 for review Message-ID: <200902281849.n1SIn2AX033825@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=158473 Change 158473 by antab@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902281849.n1SIn2AX033825>
