PERFORCE change 161645 for review

Arnar Mar Sig antab at FreeBSD.org
Wed May 6 04:31:11 UTC 2009


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

Change 161645 by antab at 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", at 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) <<<


More information about the p4-projects mailing list