summaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/asm-offsets.c3
-rw-r--r--arch/blackfin/kernel/fixed_code.S2
-rw-r--r--arch/blackfin/kernel/module.c37
-rw-r--r--arch/blackfin/kernel/process.c2
-rw-r--r--arch/blackfin/kernel/ptrace.c4
-rw-r--r--arch/blackfin/kernel/signal.c13
-rw-r--r--arch/blackfin/kernel/time-ts.c10
7 files changed, 46 insertions, 25 deletions
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index 721f15f3cebf..881afe9082c7 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -56,9 +56,6 @@ int main(void)
/* offsets into the thread struct */
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
- DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
- DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
- DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
index 5ed47228a390..4b03ba025488 100644
--- a/arch/blackfin/kernel/fixed_code.S
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -1,6 +1,6 @@
/*
* This file contains sequences of code that will be copied to a
- * fixed location, defined in <asm/atomic_seq.h>. The interrupt
+ * fixed location, defined in <asm/fixed_code.h>. The interrupt
* handlers ensure that these sequences appear to be atomic when
* executed from userspace.
* These are aligned to 16 bytes, so that we have some space to replace
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 8b9fe29d03f4..14a42848f37f 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -160,6 +160,13 @@ int
module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
char *secstrings, struct module *mod)
{
+ /*
+ * XXX: sechdrs are vmalloced in kernel/module.c
+ * and would be vfreed just after module is loaded,
+ * so we hack to keep the only information we needed
+ * in mod->arch to correctly free L1 I/D sram later.
+ * NOTE: this breaks the semantic of mod->arch structure.
+ */
Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
void *dest = NULL;
@@ -167,8 +174,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
((strcmp(".text", secstrings + s->sh_name) == 0) &&
(hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
- mod->arch.text_l1 = s;
dest = l1_inst_sram_alloc(s->sh_size);
+ mod->arch.text_l1 = dest;
if (dest == NULL) {
printk(KERN_ERR
"module %s: L1 instruction memory allocation failed\n",
@@ -182,8 +189,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
((strcmp(".data", secstrings + s->sh_name) == 0) &&
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
- mod->arch.data_a_l1 = s;
dest = l1_data_sram_alloc(s->sh_size);
+ mod->arch.data_a_l1 = dest;
if (dest == NULL) {
printk(KERN_ERR
"module %s: L1 data memory allocation failed\n",
@@ -197,8 +204,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
((strcmp(".bss", secstrings + s->sh_name) == 0) &&
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
- mod->arch.bss_a_l1 = s;
dest = l1_data_sram_alloc(s->sh_size);
+ mod->arch.bss_a_l1 = dest;
if (dest == NULL) {
printk(KERN_ERR
"module %s: L1 data memory allocation failed\n",
@@ -210,8 +217,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
s->sh_addr = (unsigned long)dest;
}
if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
- mod->arch.data_b_l1 = s;
dest = l1_data_B_sram_alloc(s->sh_size);
+ mod->arch.data_b_l1 = dest;
if (dest == NULL) {
printk(KERN_ERR
"module %s: L1 data memory allocation failed\n",
@@ -223,8 +230,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
s->sh_addr = (unsigned long)dest;
}
if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
- mod->arch.bss_b_l1 = s;
dest = l1_data_B_sram_alloc(s->sh_size);
+ mod->arch.bss_b_l1 = dest;
if (dest == NULL) {
printk(KERN_ERR
"module %s: L1 data memory allocation failed\n",
@@ -416,14 +423,14 @@ module_finalize(const Elf_Ehdr * hdr,
void module_arch_cleanup(struct module *mod)
{
- if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
- l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
- if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
- l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
- if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
- l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
- if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
- l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
- if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
- l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
+ if (mod->arch.text_l1)
+ l1_inst_sram_free((void *)mod->arch.text_l1);
+ if (mod->arch.data_a_l1)
+ l1_data_sram_free((void *)mod->arch.data_a_l1);
+ if (mod->arch.bss_a_l1)
+ l1_data_sram_free((void *)mod->arch.bss_a_l1);
+ if (mod->arch.data_b_l1)
+ l1_data_B_sram_free((void *)mod->arch.data_b_l1);
+ if (mod->arch.bss_b_l1)
+ l1_data_B_sram_free((void *)mod->arch.bss_b_l1);
}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index be9fdd00d7cb..53c2cd255441 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -245,7 +245,7 @@ unsigned long get_wchan(struct task_struct *p)
void finish_atomic_sections (struct pt_regs *regs)
{
- int __user *up0 = (int __user *)&regs->p0;
+ int __user *up0 = (int __user *)regs->p0;
if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
return;
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index b4f062c172c6..f51ab088098e 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -185,8 +185,8 @@ void ptrace_disable(struct task_struct *child)
{
unsigned long tmp;
/* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
+ tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
+ put_reg(child, PT_SYSCFG, tmp);
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index cb9d883d493c..dbc3bbf846be 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -42,6 +42,9 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+/* Location of the trace bit in SYSCFG. */
+#define TRACE_BITS 0x0001
+
struct fdpic_func_descriptor {
unsigned long text;
unsigned long GOT;
@@ -225,6 +228,16 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs->r1 = (unsigned long)(&frame->info);
regs->r2 = (unsigned long)(&frame->uc);
+ /*
+ * Clear the trace flag when entering the signal handler, but
+ * notify any tracer that was single-stepping it. The tracer
+ * may want to single-step inside the handler too.
+ */
+ if (regs->syscfg & TRACE_BITS) {
+ regs->syscfg &= ~TRACE_BITS;
+ ptrace_notify(SIGTRAP);
+ }
+
return 0;
give_sigsegv:
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 4482c47c09e5..e887efc86c29 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
static cycle_t read_cycles(void)
{
- return get_cycles();
+ return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
}
unsigned long long sched_clock(void)
@@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
break;
}
case CLOCK_EVT_MODE_ONESHOT:
- bfin_write_TSCALE(0);
+ bfin_write_TSCALE(TIME_SCALE - 1);
bfin_write_TCOUNT(0);
bfin_write_TCNTL(TMPWR | TMREN);
CSYNC();
@@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
static int __init bfin_clockevent_init(void)
{
+ unsigned long timer_clk;
+
+ timer_clk = get_cclk() / TIME_SCALE;
+
setup_irq(IRQ_CORETMR, &bfin_timer_irq);
bfin_timer_init();
- clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift);
+ clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
clockevents_register_device(&clockevent_bfin);