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