2507bc1338
The current debug trap handling code does a number of things that are illegal according to the AVR32 Architecture manual. Most importantly, it may try to schedule from Debug Mode, thus clearing the D bit, which can lead to "undefined behaviour". It seems like this works in most cases, but several people have observed somewhat unstable behaviour when debugging programs, including soft lockups. So there's definitely something which is not right with the existing code. The new code will never schedule from Debug mode, it will always exit Debug mode with a "retd" instruction, and if something not running in Debug mode needs to do something debug-related (like doing a single step), it will enter debug mode through a "breakpoint" instruction. The monitor code will then return directly to user space, bypassing its own saved registers if necessary (since we don't actually care about the trapped context, only the one that came before.) This adds three instructions to the common exception handling code, including one branch. It does not touch super-hot paths like the TLB miss handler. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
143 lines
2.7 KiB
ArmAsm
143 lines
2.7 KiB
ArmAsm
/*
|
|
* AVR32 linker script for the Linux kernel
|
|
*
|
|
* Copyright (C) 2004-2006 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.
|
|
*/
|
|
#define LOAD_OFFSET 0x00000000
|
|
#include <asm-generic/vmlinux.lds.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/thread_info.h>
|
|
|
|
OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
|
|
OUTPUT_ARCH(avr32)
|
|
ENTRY(_start)
|
|
|
|
/* Big endian */
|
|
jiffies = jiffies_64 + 4;
|
|
|
|
SECTIONS
|
|
{
|
|
. = CONFIG_ENTRY_ADDRESS;
|
|
.init : AT(ADDR(.init) - LOAD_OFFSET) {
|
|
_stext = .;
|
|
__init_begin = .;
|
|
_sinittext = .;
|
|
*(.text.reset)
|
|
*(.init.text)
|
|
/*
|
|
* .exit.text is discarded at runtime, not
|
|
* link time, to deal with references from
|
|
* __bug_table
|
|
*/
|
|
*(.exit.text)
|
|
_einittext = .;
|
|
. = ALIGN(4);
|
|
__tagtable_begin = .;
|
|
*(.taglist.init)
|
|
__tagtable_end = .;
|
|
*(.init.data)
|
|
. = ALIGN(16);
|
|
__setup_start = .;
|
|
*(.init.setup)
|
|
__setup_end = .;
|
|
. = ALIGN(4);
|
|
__initcall_start = .;
|
|
INITCALLS
|
|
__initcall_end = .;
|
|
__con_initcall_start = .;
|
|
*(.con_initcall.init)
|
|
__con_initcall_end = .;
|
|
__security_initcall_start = .;
|
|
*(.security_initcall.init)
|
|
__security_initcall_end = .;
|
|
#ifdef CONFIG_BLK_DEV_INITRD
|
|
. = ALIGN(32);
|
|
__initramfs_start = .;
|
|
*(.init.ramfs)
|
|
__initramfs_end = .;
|
|
#endif
|
|
. = ALIGN(PAGE_SIZE);
|
|
__init_end = .;
|
|
}
|
|
|
|
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
|
_evba = .;
|
|
_text = .;
|
|
*(.ex.text)
|
|
. = 0x50;
|
|
*(.tlbx.ex.text)
|
|
. = 0x60;
|
|
*(.tlbr.ex.text)
|
|
. = 0x70;
|
|
*(.tlbw.ex.text)
|
|
. = 0x100;
|
|
*(.scall.text)
|
|
*(.irq.text)
|
|
KPROBES_TEXT
|
|
TEXT_TEXT
|
|
SCHED_TEXT
|
|
LOCK_TEXT
|
|
*(.fixup)
|
|
*(.gnu.warning)
|
|
_etext = .;
|
|
} = 0xd703d703
|
|
|
|
. = ALIGN(4);
|
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
|
__start___ex_table = .;
|
|
*(__ex_table)
|
|
__stop___ex_table = .;
|
|
}
|
|
|
|
BUG_TABLE
|
|
|
|
RODATA
|
|
|
|
. = ALIGN(THREAD_SIZE);
|
|
|
|
.data : AT(ADDR(.data) - LOAD_OFFSET) {
|
|
_data = .;
|
|
_sdata = .;
|
|
/*
|
|
* First, the init task union, aligned to an 8K boundary.
|
|
*/
|
|
*(.data.init_task)
|
|
|
|
/* Then, the cacheline aligned data */
|
|
. = ALIGN(L1_CACHE_BYTES);
|
|
*(.data.cacheline_aligned)
|
|
|
|
/* And the rest... */
|
|
*(.data.rel*)
|
|
DATA_DATA
|
|
CONSTRUCTORS
|
|
|
|
_edata = .;
|
|
}
|
|
|
|
|
|
. = ALIGN(8);
|
|
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
|
|
__bss_start = .;
|
|
*(.bss)
|
|
*(COMMON)
|
|
. = ALIGN(8);
|
|
__bss_stop = .;
|
|
_end = .;
|
|
}
|
|
|
|
/* When something in the kernel is NOT compiled as a module, the module
|
|
* cleanup code and data are put into these segments. Both can then be
|
|
* thrown away, as cleanup code is never called unless it's a module.
|
|
*/
|
|
/DISCARD/ : {
|
|
*(.exit.data)
|
|
*(.exitcall.exit)
|
|
}
|
|
|
|
DWARF_DEBUG
|
|
}
|