Date: Wed, 4 Mar 2009 09:07:33 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 158659 for review Message-ID: <200903040907.n2497X1U067133@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=158659 Change 158659 by antab@antab_farm on 2009/03/04 09:07:28 Update dirty bit when page is written to. Move handler for protection fault from trap.c to pmap.c. Affected files ... .. //depot/projects/avr32/src/sys/avr32/avr32/exception.S#7 edit .. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#12 edit .. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#7 edit .. //depot/projects/avr32/src/sys/avr32/include/pmap.h#5 edit .. //depot/projects/avr32/src/sys/avr32/include/reg.h#6 edit .. //depot/projects/avr32/src/sys/avr32/include/trap.h#5 edit Differences ... ==== //depot/projects/avr32/src/sys/avr32/avr32/exception.S#7 (text+ko) ==== @@ -27,8 +27,10 @@ #include <machine/asm.h> #include <machine/at32ap700x.h> +#include <machine/reg.h> #include <machine/reg_sys.h> #include <machine/reg_intc.h> +#include <machine/pte.h> #include "assym.s" __FBSDID("$FreeBSD: $"); @@ -181,20 +183,39 @@ rete handle_protection_fault: - breakpoint PUSH_TRAPFRAME(EX) mfsr r12, AT32_SYS_ECR mov r11, sp - rcall trap_handle_protection_fault + rcall pmap_tlb_protection_fault POP_TRAPFRAME(EX) rete +/* + * Data TLB Modified. Called when memory write hits a clean page + */ handle_dtlb_modified: - PUSH_TRAPFRAME(EX) - mfsr r12, AT32_SYS_ECR - mov r11, sp - rcall trap_handle_dtlb_modified - POP_TRAPFRAME(EX) + pushm r10-r12 + /* + * Get Page table entry and set Dirty bit + */ + mfsr r10, AT32_SYS_PTBR /* Page directory */ + mfsr r11, AT32_SYS_TLBEAR /* VA */ + lsr r12, r11, PD_SHIFT + ld.w r10, r10[r12 << 2] /* Get page table */ + bfextu r12, r11, PT_SHIFT, 8 + ld.w r11, r10[r12 << 2] /* Load page entry */ + sbr r11, AT32_SYS_TLBELO_D /* Mark as durty */ + st.w r10[r12 << 2], r11 /* Store page entry */ + + /* + * Update TLB + */ + andl r11, lo(~PTE_SOFTWARE_MASK) /* Mask out software */ + sbr r11, 2 /* 4k page */ + mtsr AT32_SYS_TLBELO, r11 + tlbw /* Update tlb */ + + popm r10-r12 rete handle_breakpoint: ==== //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#12 (text+ko) ==== @@ -222,6 +222,7 @@ { mtx_assert(&vm_page_queue_mtx, MA_OWNED); if (m->md.pv_flags & PV_TABLE_MOD) { + avr32_impl(); //pmap_changebit(m, PTE_M, FALSE); TODO m->md.pv_flags &= ~PV_TABLE_MOD; } @@ -622,9 +623,9 @@ if (*pte & PTE_WIRED) { pv->pv_pmap->pm_stats.wired_count--; } - //if (*pte & PTE_M) { - // vm_page_dirty(m); - //} TODO + if (*pte & PTE_DIRTY) { + vm_page_dirty(m); + } *pte = 0; tlb_remove_entry(pv->pv_pmap, pv->pv_va); @@ -677,7 +678,7 @@ * 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) +pmap_remove_pte(struct pmap *pmap, pt_entry_t *pte, vm_offset_t va) { vm_page_t m; vm_offset_t pa; @@ -685,18 +686,18 @@ mtx_assert(&vm_page_queue_mtx, MA_OWNED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); - if (*ptq & PTE_WIRED) { + if (*pte & PTE_WIRED) { pmap->pm_stats.wired_count--; } pmap->pm_stats.resident_count--; - pa = pfn_get(*ptq); + pa = pfn_get(*pte); if (page_is_managed(pa)) { m = PHYS_TO_VM_PAGE(pa); - //if (oldpte & PTE_M) { - // vm_page_dirty(m); - //} TODO + if (*pte & PTE_DIRTY) { + vm_page_dirty(m); + } if (m->md.pv_flags & PV_TABLE_REF) { vm_page_flag_set(m, PG_REFERENCED); } @@ -706,7 +707,7 @@ pmap_remove_entry(pmap, m, va); } } - *ptq = 0; + *pte = 0; return (1); } @@ -1014,12 +1015,15 @@ /** * Called when we need to update the TLB + * XXX: Split this up, with short path written in assembly and long path + * here to call vm_fault. */ static int tlb_at = KSTACK_PAGES; 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); + struct thread *td = curthread; pt_entry_t *ent; - register_t mmucr; + register_t mmucr, intr; ent = (pt_entry_t *)pd[pd_index_from_va(tlbear)]; if (ent) { @@ -1034,10 +1038,6 @@ __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; @@ -1068,44 +1068,40 @@ PROC_UNLOCK(p); } else { map = kernel_map; - rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); } - if (rv == KERN_SUCCESS) { + if (rv != KERN_SUCCESS) { if (!TRAPF_USERMODE(tf)) { - return; + 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); + 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; + ent = (pt_entry_t *)pd[pd_index_from_va(tlbear)]; + KASSERT(ent != NULL, ("Empty pte after success from vm_fault")); + ent += pt_index_from_va(tlbear); + } -/* 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)); */ + /* Write miss, mark page as dirty */ + if (ecr == T_TLB_MISS_WRITE) { + *ent |= PTE_DIRTY; + } - breakpoint(); - panic("pmap_tlb_miss: address 0x%x not in pd %p\n", tlbear, pd); - } + /* XXX: Exceptions are enabled in the long path */ + intr = intr_disable(); mmucr = sysreg_read(MMUCR); mmucr &= ~bit_mask(SYS, MMUCR, DRP); @@ -1115,8 +1111,7 @@ sysreg_write(TLBEHI, (tlbear & bit_mask(SYS, TLBEHI, VPN)) | bit_offset(SYS, TLBEHI, V) | (bit_mask(SYS, TLBEHI, ASID) & tlbehi)); - sysreg_write(TLBELO, (*ent & ~bit_mask(SYS, TLBELO, SZ)) | PTE_DIRTY | - PTE_SIZE_4K); + sysreg_write(TLBELO, (*ent & ~PTE_SOFTWARE_MASK) | PTE_SIZE_4K); sysreg_write(MMUCR, mmucr); nop(); @@ -1128,5 +1123,28 @@ if (tlb_at == TLB_SIZE) { tlb_at = KSTACK_PAGES; } + + /* XXX */ + intr_restore(intr); + +out: + if (!TRAPF_USERMODE(tf)) { + return; + } + userret(td, tf); } +/* + * Handle protection fault + */ +void pmap_tlb_protection_fault(uint32_t ecr, struct trapframe *tf) { + pd_entry_t* pd = (pd_entry_t *)sysreg_read(PTBR); + uint32_t va = sysreg_read(TLBEAR); + pt_entry_t *ent; + + ent = (pt_entry_t *)pd[pd_index_from_va(va)]; + ent += pt_index_from_va(va); + KASSERT(ent || *ent, ("Page table entry missing in protection fault")); + + panic("Finish implementing protection fault"); +} ==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#7 (text+ko) ==== @@ -104,16 +104,3 @@ avr32_impl(); } -void trap_handle_protection_fault(uint32_t ecr, struct trapframe *frame) { - printf("Protection fault, ecr: %x\n", ecr); - trapframe_dump(frame); - tlb_dump(); - avr32_impl(); -} - -void trap_handle_dtlb_modified(uint32_t ecr, struct trapframe *frame) { - printf("DTLB modified, ecr: %x\n", ecr); - trapframe_dump(frame); - avr32_impl(); -} - ==== //depot/projects/avr32/src/sys/avr32/include/pmap.h#5 (text+ko) ==== @@ -198,6 +198,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, struct trapframe *); +void pmap_tlb_protection_fault(uint32_t ecr, struct trapframe *tf); #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/reg.h#6 (text+ko) ==== @@ -65,6 +65,17 @@ #define reg_write(offset, par, reg, value) \ __raw_write((void *)(offset + AT32_##par##_##reg), (value)) +static inline uint32_t __raw_read(const volatile void *addr) { + return *(const volatile uint32_t *)addr; +} + +static inline void __raw_write(volatile void *addr, uint32_t value) { + *(volatile uint32_t *)addr = value; +} + +#endif +#endif + #define bit_shift(par, reg, bit) \ AT32_##par##_##reg##_##bit @@ -77,14 +88,4 @@ #define bit_value(par, reg, bit, value) \ ((value >> AT32_##par##_##reg##_##bit ) & ((1 << AT32_##par##_##reg##_##bit##_SIZE) - 1)) -static inline uint32_t __raw_read(const volatile void *addr) { - return *(const volatile uint32_t *)addr; -} - -static inline void __raw_write(volatile void *addr, uint32_t value) { - *(volatile uint32_t *)addr = value; -} -#endif -#endif - #endif /* !MACHINE_REG_H */ ==== //depot/projects/avr32/src/sys/avr32/include/trap.h#5 (text+ko) ==== @@ -34,8 +34,6 @@ void trap_handle_illegal_opcode(uint32_t ecr, struct trapframe *reg); void trap_handle_breakpoint(uint32_t ecr, struct trapframe *reg); 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903040907.n2497X1U067133>