Commit e17587b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6:
  [AVR32] Fix wrong pt_regs in critical exception handler
  [AVR32] Fix copy_to_user_page() breakage
  [AVR32] Follow the rules when dealing with the OCD system
  [AVR32] Clean up OCD register usage
  [AVR32] Implement irqflags trace and lockdep support
  [AVR32] Implement stacktrace support
  [AVR32] Kconfig: Use def_bool instead of bool + default
  [AVR32] Fix invalid status register bit definitions in asm/ptrace.h
  [AVR32] Add TIF_RESTORE_SIGMASK to the work masks
parents 29ac0052 5998a3cf
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
mainmenu "Linux Kernel Configuration" mainmenu "Linux Kernel Configuration"
config AVR32 config AVR32
bool def_bool y
default y
# With EMBEDDED=n, we get lots of stuff automatically selected # With EMBEDDED=n, we get lots of stuff automatically selected
# that we usually don't need on AVR32. # that we usually don't need on AVR32.
select EMBEDDED select EMBEDDED
...@@ -20,51 +19,49 @@ config AVR32 ...@@ -20,51 +19,49 @@ config AVR32
http://avr32linux.org/. http://avr32linux.org/.
config GENERIC_GPIO config GENERIC_GPIO
bool def_bool y
default y
config GENERIC_HARDIRQS config GENERIC_HARDIRQS
bool def_bool y
default y
config STACKTRACE_SUPPORT
def_bool y
config LOCKDEP_SUPPORT
def_bool y
config TRACE_IRQFLAGS_SUPPORT
def_bool y
config HARDIRQS_SW_RESEND config HARDIRQS_SW_RESEND
bool def_bool y
default y
config GENERIC_IRQ_PROBE config GENERIC_IRQ_PROBE
bool def_bool y
default y
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool def_bool y
default y
config GENERIC_TIME config GENERIC_TIME
bool def_bool y
default y
config RWSEM_XCHGADD_ALGORITHM config RWSEM_XCHGADD_ALGORITHM
bool def_bool n
config ARCH_HAS_ILOG2_U32 config ARCH_HAS_ILOG2_U32
bool def_bool n
default n
config ARCH_HAS_ILOG2_U64 config ARCH_HAS_ILOG2_U64
bool def_bool n
default n
config GENERIC_HWEIGHT config GENERIC_HWEIGHT
bool def_bool y
default y
config GENERIC_CALIBRATE_DELAY config GENERIC_CALIBRATE_DELAY
bool def_bool y
default y
config GENERIC_BUG config GENERIC_BUG
bool def_bool y
default y
depends on BUG depends on BUG
source "init/Kconfig" source "init/Kconfig"
...@@ -139,28 +136,22 @@ config PHYS_OFFSET ...@@ -139,28 +136,22 @@ config PHYS_OFFSET
source "kernel/Kconfig.preempt" source "kernel/Kconfig.preempt"
config HAVE_ARCH_BOOTMEM_NODE config HAVE_ARCH_BOOTMEM_NODE
bool def_bool n
default n
config ARCH_HAVE_MEMORY_PRESENT config ARCH_HAVE_MEMORY_PRESENT
bool def_bool n
default n
config NEED_NODE_MEMMAP_SIZE config NEED_NODE_MEMMAP_SIZE
bool def_bool n
default n
config ARCH_FLATMEM_ENABLE config ARCH_FLATMEM_ENABLE
bool def_bool y
default y
config ARCH_DISCONTIGMEM_ENABLE config ARCH_DISCONTIGMEM_ENABLE
bool def_bool n
default n
config ARCH_SPARSEMEM_ENABLE config ARCH_SPARSEMEM_ENABLE
bool def_bool n
default n
source "mm/Kconfig" source "mm/Kconfig"
......
...@@ -11,3 +11,4 @@ obj-y += signal.o sys_avr32.o process.o time.o ...@@ -11,3 +11,4 @@ obj-y += signal.o sys_avr32.o process.o time.o
obj-y += init_task.o switch_to.o cpu.o obj-y += init_task.o switch_to.o cpu.o
obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
...@@ -21,5 +21,7 @@ void foo(void) ...@@ -21,5 +21,7 @@ void foo(void)
OFFSET(TI_flags, thread_info, flags); OFFSET(TI_flags, thread_info, flags);
OFFSET(TI_cpu, thread_info, cpu); OFFSET(TI_cpu, thread_info, cpu);
OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_preempt_count, thread_info, preempt_count);
OFFSET(TI_rar_saved, thread_info, rar_saved);
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
OFFSET(TI_restart_block, thread_info, restart_block); OFFSET(TI_restart_block, thread_info, restart_block);
} }
...@@ -264,16 +264,7 @@ syscall_exit_work: ...@@ -264,16 +264,7 @@ syscall_exit_work:
3: bld r1, TIF_BREAKPOINT 3: bld r1, TIF_BREAKPOINT
brcc syscall_exit_cont brcc syscall_exit_cont
mfsr r3, SYSREG_TLBEHI rjmp enter_monitor_mode
lddsp r2, sp[REG_PC]
andl r3, 0xff, COH
lsl r3, 1
sbr r3, 30
sbr r3, 0
mtdr DBGREG_BWA2A, r2
mtdr DBGREG_BWC2A, r3
rjmp syscall_exit_cont
/* The slow path of the TLB miss handler */ /* The slow path of the TLB miss handler */
page_table_not_present: page_table_not_present:
...@@ -288,11 +279,16 @@ page_not_present: ...@@ -288,11 +279,16 @@ page_not_present:
rjmp ret_from_exception rjmp ret_from_exception
/* This function expects to find offending PC in SYSREG_RAR_EX */ /* This function expects to find offending PC in SYSREG_RAR_EX */
.type save_full_context_ex, @function
.align 2
save_full_context_ex: save_full_context_ex:
mfsr r11, SYSREG_RAR_EX
sub r9, pc, . - debug_trampoline
mfsr r8, SYSREG_RSR_EX mfsr r8, SYSREG_RSR_EX
cp.w r9, r11
breq 3f
mov r12, r8 mov r12, r8
andh r8, (MODE_MASK >> 16), COH andh r8, (MODE_MASK >> 16), COH
mfsr r11, SYSREG_RAR_EX
brne 2f brne 2f
1: pushm r11, r12 /* PC and SR */ 1: pushm r11, r12 /* PC and SR */
...@@ -303,10 +299,25 @@ save_full_context_ex: ...@@ -303,10 +299,25 @@ save_full_context_ex:
stdsp sp[4], r10 /* replace saved SP */ stdsp sp[4], r10 /* replace saved SP */
rjmp 1b rjmp 1b
/*
* The debug handler set up a trampoline to make us
* automatically enter monitor mode upon return, but since
* we're saving the full context, we must assume that the
* exception handler might want to alter the return address
* and/or status register. So we need to restore the original
* context and enter monitor mode manually after the exception
* has been handled.
*/
3: get_thread_info r8
ld.w r11, r8[TI_rar_saved]
ld.w r12, r8[TI_rsr_saved]
rjmp 1b
.size save_full_context_ex, . - save_full_context_ex
/* Low-level exception handlers */ /* Low-level exception handlers */
handle_critical: handle_critical:
pushm r12 sub sp, 4
pushm r0-r12 stmts --sp, r0-lr
rcall save_full_context_ex rcall save_full_context_ex
mfsr r12, SYSREG_ECR mfsr r12, SYSREG_ECR
mov r11, sp mov r11, sp
...@@ -439,6 +450,7 @@ do_fpe_ll: ...@@ -439,6 +450,7 @@ do_fpe_ll:
ret_from_exception: ret_from_exception:
mask_interrupts mask_interrupts
lddsp r4, sp[REG_SR] lddsp r4, sp[REG_SR]
andh r4, (MODE_MASK >> 16), COH andh r4, (MODE_MASK >> 16), COH
brne fault_resume_kernel brne fault_resume_kernel
...@@ -515,119 +527,124 @@ fault_exit_work: ...@@ -515,119 +527,124 @@ fault_exit_work:
2: bld r1, TIF_BREAKPOINT 2: bld r1, TIF_BREAKPOINT
brcc fault_resume_user brcc fault_resume_user
mfsr r3, SYSREG_TLBEHI rjmp enter_monitor_mode
lddsp r2, sp[REG_PC]
andl r3, 0xff, COH .section .kprobes.text, "ax", @progbits
lsl r3, 1 .type handle_debug, @function
sbr r3, 30 handle_debug:
sbr r3, 0 sub sp, 4 /* r12_orig */
mtdr DBGREG_BWA2A, r2 stmts --sp, r0-lr
mtdr DBGREG_BWC2A, r3 mfsr r8, SYSREG_RAR_DBG
rjmp fault_resume_user mfsr r9, SYSREG_RSR_DBG
unmask_exceptions
/* If we get a debug trap from privileged context we end up here */ pushm r8-r9
handle_debug_priv: bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
/* Fix up LR and SP in regs. r11 contains the mode we came from */ brne debug_fixup_regs
.Ldebug_fixup_cont:
#ifdef CONFIG_TRACE_IRQFLAGS
rcall trace_hardirqs_off
#endif
mov r12, sp
rcall do_debug
mov sp, r12
lddsp r2, sp[REG_SR]
bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
brne debug_resume_kernel
get_thread_info r0
ld.w r1, r0[TI_flags]
mov r2, _TIF_DBGWORK_MASK
tst r1, r2
brne debug_exit_work
bld r1, TIF_SINGLE_STEP
brcc 1f
mfdr r4, OCD_DC
sbr r4, OCD_DC_SS_BIT
mtdr OCD_DC, r4
1: popm r10,r11
mask_exceptions
mtsr SYSREG_RSR_DBG, r11
mtsr SYSREG_RAR_DBG, r10
#ifdef CONFIG_TRACE_IRQFLAGS
rcall trace_hardirqs_on
1:
#endif
ldmts sp++, r0-lr
sub sp, -4
retd
.size handle_debug, . - handle_debug
/* Mode of the trapped context is in r9 */
.type debug_fixup_regs, @function
debug_fixup_regs:
mfsr r8, SYSREG_SR mfsr r8, SYSREG_SR
mov r9, r8 mov r10, r8
andh r8, hi(~MODE_MASK) bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
or r8, r11
mtsr SYSREG_SR, r8 mtsr SYSREG_SR, r8
sub pc, -2 sub pc, -2
stdsp sp[REG_LR], lr stdsp sp[REG_LR], lr
mtsr SYSREG_SR, r9 mtsr SYSREG_SR, r10
sub pc, -2 sub pc, -2
sub r10, sp, -FRAME_SIZE_FULL sub r8, sp, -FRAME_SIZE_FULL
stdsp sp[REG_SP], r10 stdsp sp[REG_SP], r8
mov r12, sp rjmp .Ldebug_fixup_cont
rcall do_debug_priv .size debug_fixup_regs, . - debug_fixup_regs
/* Now, put everything back */ .type debug_resume_kernel, @function
ssrf SR_EM_BIT debug_resume_kernel:
mask_exceptions
popm r10, r11 popm r10, r11
mtsr SYSREG_RAR_DBG, r10 mtsr SYSREG_RAR_DBG, r10
mtsr SYSREG_RSR_DBG, r11 mtsr SYSREG_RSR_DBG, r11
mfsr r8, SYSREG_SR #ifdef CONFIG_TRACE_IRQFLAGS
mov r9, r8 bld r11, SYSREG_GM_OFFSET
andh r8, hi(~MODE_MASK) brcc 1f
andh r11, hi(MODE_MASK) rcall trace_hardirqs_on
or r8, r11 1:
mtsr SYSREG_SR, r8 #endif
mfsr r2, SYSREG_SR
mov r1, r2
bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
mtsr SYSREG_SR, r2
sub pc, -2 sub pc, -2
popm lr popm lr
mtsr SYSREG_SR, r9 mtsr SYSREG_SR, r1
sub pc, -2 sub pc, -2
sub sp, -4 /* skip SP */ sub sp, -4 /* skip SP */
popm r0-r12 popm r0-r12
sub sp, -4 sub sp, -4
retd retd
.size debug_resume_kernel, . - debug_resume_kernel
.type debug_exit_work, @function
debug_exit_work:
/* /*
* At this point, everything is masked, that is, interrupts, * We must return from Monitor Mode using a retd, and we must
* exceptions and debugging traps. We might get called from * not schedule since that involves the D bit in SR getting
* interrupt or exception context in some rare cases, but this * cleared by something other than the debug hardware. This
* will be taken care of by do_debug(), so we're not going to * may cause undefined behaviour according to the Architecture
* do a 100% correct context save here. * manual.
*
* So we fix up the return address and status and return to a
* stub below in Exception mode. From there, we can follow the
* normal exception return path.
*
* The real return address and status registers are stored on
* the stack in the way the exception return path understands,
* so no need to fix anything up there.
*/ */
handle_debug: sub r8, pc, . - fault_exit_work
sub sp, 4 /* r12_orig */ mtsr SYSREG_RAR_DBG, r8
stmts --sp, r0-lr mov r9, 0
mfsr r10, SYSREG_RAR_DBG orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION)
mfsr r11, SYSREG_RSR_DBG mtsr SYSREG_RSR_DBG, r9
unmask_exceptions sub pc, -2
pushm r10,r11
andh r11, (MODE_MASK >> 16), COH
brne handle_debug_priv
mov r12, sp
rcall do_debug
lddsp r10, sp[REG_SR]
andh r10, (MODE_MASK >> 16), COH
breq debug_resume_user
debug_restore_all:
popm r10,r11
mask_exceptions
mtsr SYSREG_RSR_DBG, r11
mtsr SYSREG_RAR_DBG, r10
ldmts sp++, r0-lr
sub sp, -4
retd retd
.size debug_exit_work, . - debug_exit_work
debug_resume_user:
get_thread_info r0
mask_interrupts
ld.w r1, r0[TI_flags]
andl r1, _TIF_DBGWORK_MASK, COH
breq debug_restore_all
1: bld r1, TIF_NEED_RESCHED
brcc 2f
unmask_interrupts
rcall schedule
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp 1b
2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
tst r1, r2
breq 3f
unmask_interrupts
mov r12, sp
mov r11, r0
rcall do_notify_resume
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp 1b
3: bld r1, TIF_SINGLE_STEP
brcc debug_restore_all
mfdr r2, DBGREG_DC
sbr r2, DC_SS_BIT
mtdr DBGREG_DC, r2
rjmp debug_restore_all
.set rsr_int0, SYSREG_RSR_INT0 .set rsr_int0, SYSREG_RSR_INT0
.set rsr_int1, SYSREG_RSR_INT1 .set rsr_int1, SYSREG_RSR_INT1
...@@ -675,7 +692,11 @@ irq_level\level: ...@@ -675,7 +692,11 @@ irq_level\level:
andl r1, _TIF_WORK_MASK, COH andl r1, _TIF_WORK_MASK, COH
brne irq_exit_work brne irq_exit_work
1: popm r8-r9 1:
#ifdef CONFIG_TRACE_IRQFLAGS
rcall trace_hardirqs_on
#endif
popm r8-r9
mtsr rar_int\level, r8 mtsr rar_int\level, r8
mtsr rsr_int\level, r9 mtsr rsr_int\level, r9
ldmts sp++,r0-lr ldmts sp++,r0-lr
...@@ -748,3 +769,53 @@ cpu_idle_enable_int_and_exit: ...@@ -748,3 +769,53 @@ cpu_idle_enable_int_and_exit:
IRQ_LEVEL 1 IRQ_LEVEL 1
IRQ_LEVEL 2 IRQ_LEVEL 2
IRQ_LEVEL 3 IRQ_LEVEL 3
.section .kprobes.text, "ax", @progbits
.type enter_monitor_mode, @function
enter_monitor_mode:
/*
* We need to enter monitor mode to do a single step. The
* monitor code will alter the return address so that we
* return directly to the user instead of returning here.
*/
breakpoint
rjmp breakpoint_failed
.size enter_monitor_mode, . - enter_monitor_mode
.type debug_trampoline, @function
.global debug_trampoline
debug_trampoline:
/*
* Save the registers on the stack so that the monitor code
* can find them easily.
*/
sub sp, 4 /* r12_orig */
stmts --sp, r0-lr
get_thread_info r0
ld.w r8, r0[TI_rar_saved]
ld.w r9, r0[TI_rsr_saved]
pushm r8-r9
/*
* The monitor code will alter the return address so we don't
* return here.
*/
breakpoint
rjmp breakpoint_failed
.size debug_trampoline, . - debug_trampoline
.type breakpoint_failed, @function
breakpoint_failed:
/*
* Something went wrong. Perhaps the debug hardware isn't
* enabled?
*/
lda.w r12, msg_breakpoint_failed
mov r11, sp
mov r10, 9 /* SIGKILL */
call die
1: rjmp 1b
msg_breakpoint_failed:
.asciz "Failed to enter Debug Mode"
...@@ -70,9 +70,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) ...@@ -70,9 +70,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D))); BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D)));
dc = __mfdr(DBGREG_DC); dc = ocd_read(DC);
dc |= DC_SS; dc |= 1 << OCD_DC_SS_BIT;
__mtdr(DBGREG_DC, dc); ocd_write(DC, dc);
/* /*
* We must run the instruction from its original location * We must run the instruction from its original location
...@@ -91,9 +91,9 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) ...@@ -91,9 +91,9 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
pr_debug("resuming execution at PC=%08lx\n", regs->pc); pr_debug("resuming execution at PC=%08lx\n", regs->pc);
dc = __mfdr(DBGREG_DC); dc = ocd_read(DC);
dc &= ~DC_SS; dc &= ~(1 << OCD_DC_SS_BIT);
__mtdr(DBGREG_DC, dc); ocd_write(DC, dc);
*p->addr = BREAKPOINT_INSTRUCTION; *p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long)p->addr, flush_icache_range((unsigned long)p->addr,
...@@ -261,7 +261,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -261,7 +261,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
int __init arch_init_kprobes(void) int __init arch_init_kprobes(void)
{ {
printk("KPROBES: Enabling monitor mode (MM|DBE)...\n"); printk("KPROBES: Enabling monitor mode (MM|DBE)...\n");
__mtdr(DBGREG_DC, DC_MM | DC_DBE); ocd_write(DC, (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT));
/* TODO: Register kretprobe trampoline */ /* TODO: Register kretprobe trampoline */
return 0; return 0;
......
...@@ -55,8 +55,8 @@ void machine_power_off(void) ...@@ -55,8 +55,8 @@ void machine_power_off(void)
void machine_restart(char *cmd) void machine_restart(char *cmd)
{ {
__mtdr(DBGREG_DC, DC_DBE); ocd_write(DC, (1 << OCD_DC_DBE_BIT));
__mtdr(DBGREG_DC, DC_RES); ocd_write(DC, (1 << OCD_DC_RES_BIT));
while (1) ; while (1) ;
} }
...@@ -287,10 +287,11 @@ void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl) ...@@ -287,10 +287,11 @@ void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl)
regs->sr & SR_N ? 'N' : 'n', regs->sr & SR_N ? 'N' : 'n',
regs->sr & SR_Z ? 'Z' : 'z', regs->sr & SR_Z ? 'Z' : 'z',
regs->sr & SR_C ? 'C' : 'c'); regs->sr & SR_C ? 'C' : 'c');
printk("%sMode bits: %c%c%c%c%c%c%c%c%c\n", log_lvl, printk("%sMode bits: %c%c%c%c%c%c%c%c%c%c\n", log_lvl,
regs->sr & SR_H ? 'H' : 'h', regs->sr & SR_H ? 'H' : 'h',
regs->sr & SR_R ? 'R' : 'r',
regs->sr & SR_J ? 'J' : 'j', regs->sr & SR_J ? 'J' : 'j',
regs->sr & SR_DM ? 'M' : 'm',
regs->sr & SR_D ? 'D' : 'd',
regs->sr & SR_EM ? 'E' : 'e', regs->sr & SR_EM ? 'E' : 'e',
regs->sr & SR_I3M ? '3' : '.', regs->sr & SR_I3M ? '3' : '.',
regs->sr & SR_I2M ? '2' : '.', regs->sr & SR_I2M ? '2' : '.',
......
This diff is collapsed.
/*
* Stack trace management functions
*
* Copyright (C) 2007 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
register unsigned long current_frame_pointer asm("r7");
struct stackframe {
unsigned long lr;
unsigned long fp;
};
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
void save_stack_trace(struct stack_trace *trace)
{
unsigned long low, high;
unsigned long fp;
struct stackframe *frame;
int skip = trace->skip;
low = (unsigned long)task_stack_page(current);
high = low + THREAD_SIZE;
fp = current_frame_pointer;
while (fp >= low && fp <= (high - 8)) {
frame = (struct stackframe *)fp;
if (skip) {
skip--;
} else {
trace->entries[trace->nr_entries++] = frame->lr;
if (trace->nr_entries >= trace->max_entries)
break;
}
/*
* The next frame must be at a higher address than the
* current frame.
*/
low = fp + 8;
fp = frame->fp;
}
}
...@@ -39,7 +39,7 @@ void NORET_TYPE die(const char *str, struct pt_regs *regs, long err) ...@@ -39,7 +39,7 @@ void NORET_TYPE die(const char *str, struct pt_regs *regs, long err)
printk("FRAME_POINTER "); printk("FRAME_POINTER ");
#endif #endif
if (current_cpu_data.features & AVR32_FEATURE_OCD) { if (current_cpu_data.features & AVR32_FEATURE_OCD) {
unsigned long did = __mfdr(DBGREG_DID); unsigned long did = ocd_read(DID);
printk("chip: 0x%03lx:0x%04lx rev %lu\n", printk("chip: 0x%03lx:0x%04lx rev %lu\n",
(did >> 1) & 0x7ff, (did >> 1) & 0x7ff,
(did >> 12) & 0x7fff, (did >> 12) & 0x7fff,
......
...@@ -77,10 +77,10 @@ SECTIONS ...@@ -77,10 +77,10 @@ SECTIONS
. = 0x100; . = 0x100;
*(.scall.text) *(.scall.text)
*(.irq.text) *(.irq.text)
KPROBES_TEXT
TEXT_TEXT TEXT_TEXT
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
KPROBES_TEXT
*(.fixup) *(.fixup)
*(.gnu.warning) *(.gnu.warning)
_etext = .; _etext = .;
......
...@@ -122,16 +122,6 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page) ...@@ -122,16 +122,6 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
} }
} }
/*
* This one is used by copy_to_user_page()
*/
void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
unsigned long addr, int len)
{
if (vma->vm_flags & VM_EXEC)
flush_icache_range(addr, addr + len);
}
asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len) asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
{ {
int ret; int ret;
...@@ -159,3 +149,13 @@ asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len) ...@@ -159,3 +149,13 @@ asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
out: out:
return ret; return ret;
} }
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
memcpy(dst, src, len);
if (vma->vm_flags & VM_EXEC)
flush_icache_range((unsigned long)dst,
(unsigned long)dst + len);
}
...@@ -116,15 +116,16 @@ extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); ...@@ -116,15 +116,16 @@ extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
* flush with all configurations. * flush with all configurations.
*/ */
extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_icache_range(unsigned long start, unsigned long end);
extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page,
unsigned long addr, int len);
#define copy_to_user_page(vma, page, vaddr, dst, src, len) do { \ extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
memcpy(dst, src, len); \ unsigned long vaddr, void *dst, const void *src,
flush_icache_user_range(vma, page, vaddr, len); \ unsigned long len);
} while(0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ static inline void copy_from_user_page(struct vm_area_struct *vma,
memcpy(dst, src, len) struct page *page, unsigned long vaddr, void *dst,
const void *src, unsigned long len)
{
memcpy(dst, src, len);
}
#endif /* __ASM_AVR32_CACHEFLUSH_H */ #endif /* __ASM_AVR32_CACHEFLUSH_H */
This diff is collapsed.
...@@ -139,6 +139,9 @@ extern void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl); ...@@ -139,6 +139,9 @@ extern void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl);
extern void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp, extern void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp,
struct pt_regs *regs, const char *log_lvl); struct pt_regs *regs, const char *log_lvl);
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
#define KSTK_EIP(tsk) ((tsk)->thread.cpu_context.pc) #define KSTK_EIP(tsk) ((tsk)->thread.cpu_context.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.cpu_context.ksp) #define KSTK_ESP(tsk) ((tsk)->thread.cpu_context.ksp)
......
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
/* /*
* Status Register bits * Status Register bits
*/ */
#define SR_H 0x40000000 #define SR_H 0x20000000
#define SR_R 0x20000000
#define SR_J 0x10000000 #define SR_J 0x10000000
#define SR_DM 0x08000000 #define SR_DM 0x08000000
#define SR_D 0x04000000 #define SR_D 0x04000000
...@@ -35,8 +34,7 @@ ...@@ -35,8 +34,7 @@
#define SR_I0M 0x00020000 #define SR_I0M 0x00020000
#define SR_GM 0x00010000 #define SR_GM 0x00010000
#define SR_H_BIT 30 #define SR_H_BIT 29
#define SR_R_BIT 29
#define SR_J_BIT 28 #define SR_J_BIT 28
#define SR_DM_BIT 27 #define SR_DM_BIT 27
#define SR_D_BIT 26 #define SR_D_BIT 26
......
...@@ -93,6 +93,8 @@ ...@@ -93,6 +93,8 @@
#define SYSREG_I3M_SIZE 1 #define SYSREG_I3M_SIZE 1
#define SYSREG_EM_OFFSET 21 #define SYSREG_EM_OFFSET 21
#define SYSREG_EM_SIZE 1 #define SYSREG_EM_SIZE 1
#define SYSREG_MODE_OFFSET 22
#define SYSREG_MODE_SIZE 3
#define SYSREG_M0_OFFSET 22 #define SYSREG_M0_OFFSET 22
#define SYSREG_M0_SIZE 1 #define SYSREG_M0_SIZE 1
#define SYSREG_M1_OFFSET 23 #define SYSREG_M1_OFFSET 23
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
#include <asm/ocd.h> #include <asm/ocd.h>
#define finish_arch_switch(prev) \ #define finish_arch_switch(prev) \
do { \ do { \
__mtdr(DBGREG_PID, prev->pid); \ ocd_write(PID, prev->pid); \
__mtdr(DBGREG_PID, current->pid); \ ocd_write(PID, current->pid); \
} while(0) } while(0)
#endif #endif
......
...@@ -25,6 +25,11 @@ struct thread_info { ...@@ -25,6 +25,11 @@ struct thread_info {
unsigned long flags; /* low level flags */ unsigned long flags; /* low level flags */
__u32 cpu; __u32 cpu;
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */ __s32 preempt_count; /* 0 => preemptable, <0 => BUG */
__u32 rar_saved; /* return address... */
__u32 rsr_saved; /* ...and status register
saved by debug handler
when setting up
trampoline */
struct restart_block restart_block; struct restart_block restart_block;
__u8 supervisor_stack[0]; __u8 supervisor_stack[0];
}; };
...@@ -78,8 +83,8 @@ static inline struct thread_info *current_thread_info(void) ...@@ -78,8 +83,8 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */ TIF_NEED_RESCHED */
#define TIF_BREAKPOINT 4 /* true if we should break after return */ #define TIF_BREAKPOINT 4 /* enter monitor mode on return */
#define TIF_SINGLE_STEP 5 /* single step after next break */ #define TIF_SINGLE_STEP 5 /* single step in progress */
#define TIF_MEMDIE 6 #define TIF_MEMDIE 6
#define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */
#define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */
...@@ -89,18 +94,24 @@ static inline struct thread_info *current_thread_info(void) ...@@ -89,18 +94,24 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_BREAKPOINT (1 << TIF_BREAKPOINT)
#define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP) #define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
/* XXX: These two masks must never span more than 16 bits! */ /* Note: The masks below must never span more than 16 bits! */
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK 0x0000013e #define _TIF_WORK_MASK \
((1 << TIF_SIGPENDING) \
| (1 << TIF_NEED_RESCHED) \
| (1 << TIF_POLLING_NRFLAG) \
| (1 << TIF_BREAKPOINT) \
| (1 << TIF_RESTORE_SIGMASK))
/* work to do on any return to userspace */ /* work to do on any return to userspace */
#define _TIF_ALLWORK_MASK 0x0000013f #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE))
/* work to do on return from debug mode */ /* work to do on return from debug mode */
#define _TIF_DBGWORK_MASK 0x0000017e #define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
#endif /* __ASM_AVR32_THREAD_INFO_H */ #endif /* __ASM_AVR32_THREAD_INFO_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment