Date: Wed, 6 May 2009 04:31:09 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 161645 for review Message-ID: <200905060431.n464V92W081688@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161645 Change 161645 by antab@antab_farm on 2009/05/06 04:30:51 * Change interrupt levels, 0 is lowest priority, 3 highest. 0 will be perm masked and all irq on 3 by default. * Rewrite trap handling. more like other archs now with one trap() * Move page fault handler to trap.c and go thru trap() * db_backtrace/stack_capture to use INKERNEL instead of in thread stack. Comment out INKERNEL for db_backtrace to allow traceing into userspace for now. Affected files ... .. //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#10 edit .. //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#5 edit .. //depot/projects/avr32/src/sys/avr32/avr32/exception.S#11 edit .. //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#4 edit .. //depot/projects/avr32/src/sys/avr32/avr32/intr.c#7 edit .. //depot/projects/avr32/src/sys/avr32/avr32/pm_machdep.c#6 edit .. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#17 edit .. //depot/projects/avr32/src/sys/avr32/avr32/stack_machdep.c#4 edit .. //depot/projects/avr32/src/sys/avr32/avr32/support.S#11 edit .. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#8 edit .. //depot/projects/avr32/src/sys/avr32/include/asm.h#4 edit .. //depot/projects/avr32/src/sys/avr32/include/cpu.h#5 edit .. //depot/projects/avr32/src/sys/avr32/include/db_machdep.h#5 edit .. //depot/projects/avr32/src/sys/avr32/include/intr.h#6 edit .. //depot/projects/avr32/src/sys/avr32/include/trap.h#7 edit Differences ... ==== //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#10 (text+ko) ==== @@ -57,6 +57,7 @@ #include <machine/pmap.h> #include <machine/debug.h> #include <machine/intr.h> +#include <machine/trap.h> #include <machine/reg.h> #include <machine/reg_sys.h> #include <machine/reg_ocd.h> @@ -71,7 +72,7 @@ { /* Set exception vector */ sysreg_write(EVBA, (uint32_t)&_evba); - __asm__ __volatile__ ("csrf %0" : : "i"(AT32_SYS_SR_EM)); + trap_enable(); #if defined(DDB) /* @@ -91,8 +92,8 @@ { /* Make sure important interrupts are enabled before we do this. */ if (sysreg_read(SR) & (bit_offset(SYS, SR, GM) | - bit_offset(SYS, SR, EM) | bit_offset(SYS, SR, I0M) | - bit_offset(SYS, SR, I1M))) + bit_offset(SYS, SR, EM) | bit_offset(SYS, SR, I3M) | + bit_offset(SYS, SR, I2M))) panic("sleeping with critical interrupts masked"); __asm__ __volatile ("sleep %0" : : "i"(AT32AP700X_SLEEP_IDLE)); } ==== //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#5 (text+ko) ==== @@ -37,10 +37,10 @@ #include <ddb/ddb.h> #include <ddb/db_sym.h> +#include <machine/vmparam.h> #include <machine/db_machdep.h> #include <machine/md_var.h> #include <machine/pcb.h> -#include <machine/debug.h> static void db_backtrace(struct thread *thr, struct db_frame *frame, int count); @@ -75,10 +75,19 @@ int db_trace_thread(struct thread *thr, int count) { + struct db_frame firstframe, *frame; struct pcb *ctx; ctx = kdb_thr_ctx(thr); - db_backtrace(thr, (struct db_frame *)ctx->pcb_regs.regs.r7, count); + if (ctx->pcb_regs.regs.pc != 0) { + firstframe.fp = (struct db_frame *)ctx->pcb_regs.regs.r7; + firstframe.lr = ctx->pcb_regs.regs.pc; + frame = &firstframe; + } else { + frame = (struct db_frame *)ctx->pcb_regs.regs.r7; + } + + db_backtrace(thr, frame, count); return (0); } @@ -111,10 +120,11 @@ db_printf("\n"); frame = frame->fp; - if ((vm_offset_t)frame >= thr->td_kstack && - (vm_offset_t)frame <= thr->td_kstack + - (KSTACK_PAGES * PAGE_SIZE)) { - db_printf("Frame pointer %p not in stack\n", frame); + if (frame == NULL || frame->lr == 0) { + /* XXX: Should check if in kernel, but relax that for now to + * allow tracing into userspace. + * if (!INKERNEL(frame) || !INKERNEL(frame->lr)) { + */ return; } } ==== //depot/projects/avr32/src/sys/avr32/avr32/exception.S#11 (text+ko) ==== @@ -27,6 +27,7 @@ #include <machine/asm.h> #include <machine/param.h> +#include <machine/cpu.h> #include <machine/at32ap700x.h> #include <machine/reg.h> #include <machine/reg_sys.h> @@ -38,45 +39,13 @@ __FBSDID("$FreeBSD: $"); -/* Save a trapfrome to stack */ -#define PUSH_TRAPFRAME(context) \ - sub sp, 4; \ - stmts --sp, r0-lr; \ - mfsr r11, AT32_SYS_RAR_##context; \ - mfsr r12, AT32_SYS_RSR_##context; \ - pushm r11-r12; - -/* Restore trapframe from stack */ -#define POP_TRAPFRAME(context) \ - popm r11-r12; \ - mtsr AT32_SYS_RAR_##context, r11; \ - mtsr AT32_SYS_RSR_##context, r12; \ - ldmts sp++, r0-lr; \ - sub sp, -4; - -/* Handle IRQ */ -#define IRQ(num) \ - GLOBAL(intr_handle##num); \ - PUSH_TRAPFRAME(INT##num); \ - mov r10, num; \ - lddpc r12, intr_cause_offset##num; \ - ld.w r11, r12; \ - mov r12, sp; \ - call intr_handle; \ - POP_TRAPFRAME(INT##num); \ - rete; \ -intr_cause_offset##num:; \ - .long AT32AP700X_BASE + AT32AP700X_INTC_OFFSET + \ - AT32_INTC_ICR0 - (4 * num); - .section .text.evba,"ax",@progbits - .align 2 GLOBAL(exception_vector) .align 2 /* 0x00 Unrecoverable exception */ bral handle_critical .align 2 /* 0x04 TLB multiple hit */ - bral tlb_critical + bral handle_tlb_exception .align 2 /* 0x08 Bus error data fetch */ bral handle_bus_data_fetch_error .align 2 /* 0x0C Bus error instruction fetch */ @@ -84,29 +53,29 @@ .align 2 /* 0x10 nmi */ bral handle_mni .align 2 /* 0x14 Instruction Address */ - bral handle_address_fault + bral handle_tlb_exception .align 2 /* 0x18 ITLB Protection */ - bral handle_protection_fault + bral handle_tlb_exception .align 2 /* 0x1C Breakpoint */ bral handle_breakpoint .align 2 /* 0x20 Illegal opcode */ - bral handle_illegal_opcode + bral handle_exception .align 2 /* 0x24 Unimplemented instruction */ - bral handle_illegal_opcode + bral handle_exception .align 2 /* 0x28 Privilege violation */ - bral handle_illegal_opcode + bral handle_exception .align 2 /* 0x2C FPU */ - bral handle_illegal_opcode + bral handle_exception .align 2 /* 0x30 Coprocessor absent */ - bral handle_illegal_opcode + bral handle_exception .align 2 /* 0x34 Data Address (Read) */ - bral handle_address_fault + bral handle_tlb_exception .align 2 /* 0x38 Data Address (Write) */ - bral handle_address_fault + bral handle_tlb_exception .align 2 /* 0x3C DTLB Protection (Read) */ - bral handle_protection_fault + bral handle_tlb_exception .align 2 /* 0x40 DTLB Protection (Write) */ - bral handle_protection_fault + bral handle_tlb_exception .align 2 /* 0x44 DTLB Modified */ bral handle_dtlb_modified @@ -128,7 +97,8 @@ .section .text.evba.syscall /* 0x100 Supervisor call */ ENTRY(supervisor_call) PUSH_TRAPFRAME(SUP) - /* call C syscall handler */ + mov r12, sp + rcall trap_syscall POP_TRAPFRAME(SUP) rets END(supervisor_call) @@ -203,11 +173,11 @@ popm r0-r3 PUSH_TRAPFRAME(EX) mfsr r12, AT32_SYS_ECR - mfsr r11, AT32_SYS_TLBEAR - mfsr r10, AT32_SYS_TLBEHI - mov r9, sp + mov r11, sp + mfsr r10, AT32_SYS_TLBEAR + mfsr r9, AT32_SYS_TLBEHI csrf AT32_SYS_SR_EM /* Enable exceptions */ - rcall pmap_tlb_miss + rcall trap POP_TRAPFRAME(EX) rete @@ -216,21 +186,47 @@ END(tlb_miss) /* + * Data TLB Modified. Called when memory write hits a clean page + */ +ENTRY(handle_dtlb_modified) + 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 +END(handle_dtlb_modified) + +/* * Steal proc0 stack, maybe we are here because of stack fault * and we are fucked anyway. */ ENTRY(handle_critical) - breakpoint - mov r12, 0 - rcall panic + PUSH_TRAPFRAME(EX) + mfsr r12, AT32_SYS_ECR + mov r11, sp + call trap + POP_TRAPFRAME(EX) rete END(handle_critical) -ENTRY(tlb_critical) - breakpoint - rete -END(tlb_critical) - ENTRY(handle_bus_data_fetch_error) breakpoint rete @@ -241,81 +237,91 @@ rete END(handle_bus_instruction_fetch_error) +/** + * Trap running i MNI mode + * NOTE: arg 3 and 4 are not passed to trap() + */ ENTRY(handle_mni) PUSH_TRAPFRAME(NMI) - mov r12, sp - rcall intr_handle_mni + mfsr r12, AT32_SYS_ECR + mov r11, sp + call trap POP_TRAPFRAME(NMI) rete END(handle_mni) -ENTRY(handle_illegal_opcode) +/** + * Trap running in Exception mode + * NOTE: arg 3 and 4 are not passed to trap() + */ +ENTRY(handle_exception) PUSH_TRAPFRAME(EX) mfsr r12, AT32_SYS_ECR mov r11, sp - rcall trap_handle_illegal_opcode + call trap + call handle_ast POP_TRAPFRAME(EX) rete -END(handle_illegal_opcode) +END(handle_exception) -ENTRY(handle_address_fault) +/** + * Trap running in Exception mode + */ +ENTRY(handle_tlb_exception) PUSH_TRAPFRAME(EX) - mfsr r12, AT32_SYS_ECR + mfsr r12, AT32_SYS_ECR mov r11, sp - breakpoint - rcall trap_handle_address_fault + mfsr r10, AT32_SYS_TLBEAR + mfsr r9, AT32_SYS_TLBEHI + call trap + call handle_ast POP_TRAPFRAME(EX) rete -END(handle_address_fault) +END(handle_tlb_exception) -ENTRY(handle_protection_fault) - PUSH_TRAPFRAME(EX) - mfsr r12, AT32_SYS_ECR - mov r11, sp - rcall pmap_tlb_protection_fault - POP_TRAPFRAME(EX) - rete -END(handle_protection_fault) - -/* - * Data TLB Modified. Called when memory write hits a clean page +/** + * Trap running in debug mode */ -ENTRY(handle_dtlb_modified) - 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 -END(handle_dtlb_modified) - ENTRY(handle_breakpoint) PUSH_TRAPFRAME(DBG) - mov r12, AT32_SYS_ECR + /* ECR is not updated on entering debug mode */ + mov r12, T_BREAKPOINT mov r11, sp - csrf AT32_SYS_SR_EM - rcall trap_handle_breakpoint + csrf AT32_SYS_SR_EM /* Reenable exceptions */ + call trap + call handle_ast POP_TRAPFRAME(DBG) retd END(handle_breakpoint) +/** + * Check for and process asynchronous software trap + */ +ENTRY(handle_ast) + ld.w r12, sp /* Load SR */ + bfextu r12, r12, AT32_SYS_SR_MODE, AT32_SYS_SR_MODE_SIZE + cp.w r12, AVR32_MODE_USER /* Returning to user mode ? */ + retne sp /* No */ + + ssrf AT32_SYS_SR_GM /* Disable interrupts */ + lddpc r11, handle_ast_flags /* Thread flags to check */ + lddpc r12, handle_ast_curthread /* Pointer to curthread */ + ld.w r12, r12 + ld.w r12, r12[TD_FLAGS] /* Thread flags */ + and r12, r11 + reteq sp /* Flags not set */ + + csrf AT32_SYS_SR_GM /* Enable interrupts */ + mov r12, sp /* SP still points to the trap frame */ + rjmp ast /* Call ast(frame) */ + +handle_ast_flags: + .long TDF_ASTPENDING | TDF_NEEDRESCHED +handle_ast_curthread: + .long _C_LABEL(__pcpu) + PC_CURTHREAD +END(handle_ast) + + IRQ(0) IRQ(1) IRQ(2) ==== //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#4 (text+ko) ==== @@ -37,10 +37,15 @@ #include <vm/pmap.h> #include <machine/frame.h> -ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); -ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); -ASSYM(TD_PCB_SIZE, sizeof(struct trapframe)); -ASSYM(TD_KPTE, offsetof(struct thread, td_md.md_kpte)); -ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); -ASSYM(PMAP_ASID, offsetof(struct pmap, pm_asid)); -ASSYM(PMAP_PD, offsetof(struct pmap, pm_pd)); +ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); +ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); +ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); +ASSYM(TD_PCB_SIZE, sizeof(struct trapframe)); +ASSYM(TD_KPTE, offsetof(struct thread, td_md.md_kpte)); +ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); +ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); +ASSYM(PMAP_ASID, offsetof(struct pmap, pm_asid)); +ASSYM(PMAP_PD, offsetof(struct pmap, pm_pd)); + +ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); +ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); ==== //depot/projects/avr32/src/sys/avr32/avr32/intr.c#7 (text+ko) ==== @@ -60,6 +60,12 @@ static int intrcnt_tab[IRQ_COUNT]; static int intrcnt_index = 0; extern vm_offset_t _evba; +static register_t intr_ipr[IRQ_PRIORITY_COUNT] = { + (register_t)intr_handle0, + (register_t)intr_handle1, + (register_t)intr_handle2, + (register_t)intr_handle3, +}; /* Code */ register_t @@ -90,23 +96,24 @@ void intr_init() { - size_t offset; int i; - /* Setup INTC, every interrupt is at priority 0 */ + /* Set intr_ipr for later use when changing priorities */ + for (i = 0; i < IRQ_PRIORITY_COUNT; i++) { + intr_ipr[i] = (intr_ipr[i] - (register_t)&_evba) | + (i << bit_shift(INTC, IPR, INTLEVEL)); + } + + /* Setup INTC, every interrupt is at priority 3 (highest) */ for (i = 0; i < IRQ_COUNT; i++) { - intr_intlevel[i] = 0; - offset = AT32AP700X_BASE + AT32AP700X_INTC_OFFSET + - (i * sizeof(register_t)); - - reg_write(offset, INTC, IPR, - (vm_offset_t)intr_handle0 - (vm_offset_t)&_evba); + intr_intlevel[i] = 3; + intr_change_priority(i, intr_intlevel[i]); } - /* Enable interrupts, note, INT3 is always masked */ + /* Enable interrupts, note, INT0 is always masked */ sysreg_write(COMPARE, 0); sysreg_write(SR, (sysreg_read(SR) & ~INTR_MASK) | - bit_offset(SYS, SR, I3M)); + bit_offset(SYS, SR, I0M)); } static void @@ -116,13 +123,11 @@ /* Few sanity checks */ KASSERT(irq < IRQ_COUNT, ("Invalid interrupt group")); - KASSERT(pri < 4, ("Invalid priority level")); + KASSERT(pri < IRQ_PRIORITY_COUNT, ("Invalid priority level")); offset = AT32AP700X_BASE + AT32AP700X_INTC_OFFSET + (irq * sizeof(register_t)); - reg_write(offset, INTC, IPR, - (reg_read(offset, INTC, IPR) & ~bit_mask(INTC, IPR, INTLEVEL)) | - (pri << bit_shift(INTC, IPR, INTLEVEL))); + reg_write(offset, INTC, IPR, intr_ipr[pri]); } void @@ -140,7 +145,7 @@ /* Sanity check */ KASSERT(irq < IRQ_COUNT, ("Invalid interrupt group")); - intr_change_priority(irq, 3); + intr_change_priority(irq, 0); } void @@ -188,7 +193,6 @@ struct intr_event *event; int error; - event = intr_event[irq]; avr32_mask_irq(irq); ==== //depot/projects/avr32/src/sys/avr32/avr32/pm_machdep.c#6 (text+ko) ==== @@ -69,7 +69,6 @@ void exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) { - /* Clear frame and set init register values, SP must be word aligned */ bzero((char *)td->td_frame, sizeof(struct trapframe)); td->td_frame->regs.r11 = ps_strings; @@ -77,8 +76,8 @@ td->td_frame->regs.sp = ((register_t)stack) & ~(sizeof(register_t) - 1); td->td_frame->regs.pc = entry; - /* Run in user mode, make sure INT3 is always masked */ - td->td_frame->regs.sr = AVR32_MODE_USER | bit_offset(SYS, SR, I3M); + /* Run in user mode, make sure INT0 is always masked */ + td->td_frame->regs.sr = AVR32_MODE_USER | bit_offset(SYS, SR, I0M); } int @@ -115,6 +114,7 @@ void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { + panic("sendsig"); avr32_impl(); } ==== //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#17 (text+ko) ==== @@ -361,16 +361,33 @@ return (rv); } +/* + * Copy the range specified by src_addr/len from the source map to + * the range dst_addr/len in the destination map. + * + * This routine is only advisory and need not do anything. + */ void -pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, vm_offset_t src_addr) +pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, + vm_size_t len, vm_offset_t src_addr) { - avr32_impl(); } + void pmap_copy_page(vm_page_t src, vm_page_t dst) { - avr32_impl(); + vm_paddr_t phy_src = AVR32_PHYS_TO_P2(VM_PAGE_TO_PHYS(src)); + vm_paddr_t phy_dst = AVR32_PHYS_TO_P2(VM_PAGE_TO_PHYS(dst)); + + /** + * XXX: We assume we can addres the page to copy thru P2 segment. + * this should work for most cases + */ + KASSERT(phy_src < 0xC0000000, ("src address cant be addressed in P2")); + KASSERT(phy_dst < 0xC0000000, ("dst address cant be addressed in P2")); + + bcopy((caddr_t)phy_src, (caddr_t)phy_dst, PAGE_SIZE); } void @@ -477,7 +494,6 @@ pte = pmap_pte(pmap, va); if (pte == NULL) { - printf("mpte: %x\n", mpte); panic("pmap_enter: Invalid page directory, va=0x%08X\n", va); } pa = VM_PAGE_TO_PHYS(m); @@ -1345,116 +1361,3 @@ } } -/* - * Called on page fault - */ -uint32_t 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; - 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)) { - 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); - avr32_debug("trap out\n"); - goto out; - } - - 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); - - /* Write miss, mark page as dirty */ - if (ecr == T_TLB_MISS_WRITE) { - *ent |= PTE_DIRTY; - } - - mmucr = sysreg_read(MMUCR); - mmucr &= ~bit_mask(SYS, MMUCR, DRP); - mmucr |= tlb_at << bit_shift(SYS, MMUCR, DRP); - - /* Insert into TLB */ - sysreg_write(TLBEHI, (tlbehi & bit_mask(SYS, TLBEHI, VPN)) | - bit_offset(SYS, TLBEHI, V) | - (bit_mask(SYS, TLBEHI, ASID) & tlbehi)); - sysreg_write(TLBELO, (*ent & ~PTE_SOFTWARE_MASK) | PTE_SIZE_4K); - sysreg_write(MMUCR, mmucr); - nop(); - - /* Write and sync pipeline */ - __builtin_tlbw(); - cpu_sync_pipeline(); - - tlb_at++; - if (tlb_at == TLB_SIZE) { - tlb_at = KSTACK_PAGES; - } - -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")); - - tlb_dump(); - panic("Finish implementing protection fault"); -} ==== //depot/projects/avr32/src/sys/avr32/avr32/stack_machdep.c#4 (text+ko) ==== @@ -6,7 +6,8 @@ #include <sys/param.h> #include <sys/proc.h> #include <sys/stack.h> -#include <machine/debug.h> + +#include <machine/vmparam.h> #include <machine/db_machdep.h> static void @@ -14,15 +15,9 @@ { stack_zero(st); for (; frame != NULL; frame = frame->fp) { - if ((vm_offset_t)frame < td->td_kstack && - (vm_offset_t)frame > td->td_kstack + - (KSTACK_PAGES * PAGE_SIZE)) { + if (!INKERNEL(frame) || !INKERNEL(frame->lr)) { break; } - if (frame->lr == 0) { - break; - } - if (stack_put(st, frame->lr) == -1) { break; } ==== //depot/projects/avr32/src/sys/avr32/avr32/support.S#11 (text+ko) ==== @@ -121,13 +121,29 @@ /** * Copy specified amount of data from user space into the kernel - * copyin(from, to, len) - * caddr_t *from; (user source address) - * caddr_t *to; (kernel destination address) - * unsigned len; + * copyin(from, to, len) + * r12: caddr_t *from; (user source address) + * r11: caddr_t *to; (kernel destination address) + * r10: unsigned len; */ ENTRY(copyin) - breakpoint + stm --sp, r7,lr /* Create call frame */ + mov r7, sp /* Set framepointer */ + + lddpc r9, copyin_split /* Load max userspace address */ + cp.w r9, r12 /* Is to address within user space ? */ + brge copyin_fault /* No */ + + call bcopy /* bcopy does all the work */ + mov r12, 0 /* Return 0 */ + ldm sp++, r7,pc /* Restore framepoiner and return */ + +copyin_fault: + mov r12, EFAULT + ldm sp++, r7,pc /* Restore framepoiner and return */ + +copyin_split: + .long 0x80000000 /* Max userspace address */ END(copyin) /** ==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#8 (text+ko) ==== @@ -30,10 +30,15 @@ #include "opt_md.h" #include "opt_ddb.h" #include "opt_kdb.h" +#include "opt_kdb.h" +#include "opt_kdtrace.h" +#include "opt_ktrace.h" #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> +#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/buf.h> #include <sys/bus.h> #include <sys/conf.h> @@ -50,10 +55,23 @@ #include <sys/vmmeter.h> #include <sys/cons.h> #include <sys/kdb.h> +#include <sys/resourcevar.h> +#include <sys/signalvar.h> +#include <sys/syscall.h> +#include <sys/sysent.h> +#include <sys/uio.h> +#ifdef KTRACE +#include <sys/ktrace.h> +#endif +#include <security/audit/audit.h> #include <vm/vm.h> -#include <vm/vm_object.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_kern.h> +#include <vm/vm_map.h> #include <vm/vm_page.h> +#include <vm/vm_extern.h> #include <machine/cpu.h> #include <machine/tlb.h> @@ -63,12 +81,465 @@ #include <machine/reg.h> #include <machine/reg_sys.h> + + +static void trap_kernel(uint32_t type, struct trapframe *frame, + register_t tlbear, register_t tlbehi, struct thread *td); +static int trap_pfault(uint32_t type, struct trapframe *frame, + register_t tlbear, register_t tlbehi, struct thread *td); +static void trap_fatal(uint32_t type, struct trapframe *frame); +static char *trap_name(uint32_t type); + +extern char *syscallnames[]; + +/* + * Trap names, copied from AVR32 Architecture Manual, capture 7.3 table 7-1 + */ +static char *trap_names[] = { + "Unrecoverable exception", /* T_CRITICAL */ + "TLB multiple hit", /* T_TLB_MULTIPLE_HIT */ + "Bus error data fetch", /* T_BUS_DATA_FETCH_ERROR */ + "Bus error instruction fetch", /* T_BUS_INSTRUCTION_FETCH_ERROR */ + "NMI", /* T_NMI */ + "Instruction Address", /* T_INSTRUCTION_ALIGNMENT */ + "ITLB Protection", /* T_TLB_PROT_EXECUTE */ + "Breakpoint", /* T_BREAKPOINT */ + "Illegal Opcode", /* T_ILLEGAL_OPCODE */ + "Unimplemented instruction", /* T_UNIMPLEMENTED_OPCODE */ + "Privilege violation", /* T_PRIVILEGE_VIOLATION */ + "Floating-point", /* T_FLOATING_POINT */ + "Coprocessor absent", /* T_COPROCESSOR */ + "Data Address (Read)", /* T_DATA_READ_ALIGNMENT */ + "Data Address (Write)", /* T_DATA_WRITE_ALIGNMENT */ + "DTLB Protection (Read)", /* T_TLB_PROT_READ */ + "DTLB Protection (Write)", /* T_TLB_PROT_WRITE */ + "DTLB Modified", /* T_TLB_MODIFIED */ + "ITLB Miss", /* T_TLB_MISS_EXECUTE */ + "DTLB Miss (Read)", /* T_TLB_MISS_READ */ + "DTLB Miss (Write)", /* T_TLB_MISS_WRITE */ + "Supervisor call", /* T_SYSCALL */ +}; + +#ifdef KDB +static int kdb_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RW, + &kdb_on_nmi, 0, "Go to KDB on NMI"); +#endif +static int panic_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW, + &panic_on_nmi, 0, "Panic on NMI"); + + +void +trap(uint32_t type, struct trapframe *frame, register_t tlbear, register_t tlbehi) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + int signo = 0, ucode = 0; + register_t addr; + ksiginfo_t ksi; + + PCPU_INC(cnt.v_trap); + +#ifdef KDB + if (kdb_active) { + kdb_reenter(); + return; + } +#endif + + + if (type == T_NMI) { +#ifdef KDB + if (kdb_on_nmi) { + printf("NMI ... going to debugger\n"); + kdb_trap(type, 0, frame); + } +#endif /* KDB */ + if (panic_on_nmi) { + panic("NMI indicates hardware failure"); + } + return; + } + + /* Trap in kernel mode */ + if (!TRAPF_USERMODE(frame)) { + trap_kernel(type, frame, tlbear, tlbehi, td); + return; + } + + /* + * Re-enable traps before handling usermode traps + */ + trap_enable(); + + td->td_pticks = 0; + td->td_frame = frame; + addr = frame->regs.pc; + if (td->td_ucred != p->p_ucred) { + cred_update_thread(td); + } + + switch (type) { + case T_TLB_MISS_EXECUTE: + case T_TLB_MISS_READ: + case T_TLB_MISS_WRITE: + addr = tlbear; + signo = trap_pfault(type, frame, tlbear, tlbehi, td); + + if (signo == KERN_SUCCESS) { + goto out; + } + ucode = (signo == SIGSEGV) ? SEGV_MAPERR : SEGV_ACCERR; + break; + + case T_PRIVILEGE_VIOLATION: + signo = SIGILL; + ucode = ILL_PRVOPC; + break; + + case T_BREAKPOINT: + /* + * XXX: Break into kdb until we have userspace and working gdb + */ + kdb_trap(type, 0, frame); + return; +#if 0 + signo = SIGTRAP; + ucode = TRAP_BRKPT; + break; +#endif + + case T_ILLEGAL_OPCODE: + case T_UNIMPLEMENTED_OPCODE: + signo = SIGILL; + ucode = ILL_ILLOPC; + break; + + case T_FLOATING_POINT: + signo = SIGFPE; + ucode = FPE_FLTINV; + break; + + case T_COPROCESSOR: + signo = SIGILL; + ucode = ILL_COPROC; + break; + + case T_DATA_READ_ALIGNMENT: + case T_DATA_WRITE_ALIGNMENT: >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905060431.n464V92W081688>