aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-01-12 03:55:10 -0500
committerMichal Simek <monstr@monstr.eu>2010-03-11 08:07:32 -0500
commit777537905744c28b02c283692e7f75f5445c1afa (patch)
tree57cde0f7938efaf1eb54b69b9d149c867f714e2c /arch/microblaze
parent733cc2183116b216abb52e709709bb0e626c9a75 (diff)
microblaze: Add support from PREEMPT
This patch add core PREEMPT support for Microblaze. I tried to trace it via tracers and I was able to see any output. I also added low level debug functions to see if that code is called. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/include/asm/tlbflush.h2
-rw-r--r--arch/microblaze/kernel/asm-offsets.c1
-rw-r--r--arch/microblaze/kernel/entry.S25
3 files changed, 26 insertions, 2 deletions
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h
index 10ec70cd8735..bcb8b41d55af 100644
--- a/arch/microblaze/include/asm/tlbflush.h
+++ b/arch/microblaze/include/asm/tlbflush.h
@@ -23,7 +23,7 @@
23extern void _tlbie(unsigned long address); 23extern void _tlbie(unsigned long address);
24extern void _tlbia(void); 24extern void _tlbia(void);
25 25
26#define __tlbia() _tlbia() 26#define __tlbia() { preempt_disable(); _tlbia(); preempt_enable(); }
27 27
28static inline void local_flush_tlb_all(void) 28static inline void local_flush_tlb_all(void)
29 { __tlbia(); } 29 { __tlbia(); }
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
index 7bc7b68f97db..0071260a672c 100644
--- a/arch/microblaze/kernel/asm-offsets.c
+++ b/arch/microblaze/kernel/asm-offsets.c
@@ -90,6 +90,7 @@ int main(int argc, char *argv[])
90 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 90 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
91 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); 91 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
92 DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context)); 92 DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
93 DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
93 BLANK(); 94 BLANK();
94 95
95 /* struct cpu_context */ 96 /* struct cpu_context */
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 3bad4ff49471..1a6729dde49e 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -853,7 +853,30 @@ no_intr_resched:
853 lwi r1, r1, PT_R1 - PT_SIZE; 853 lwi r1, r1, PT_R1 - PT_SIZE;
854 bri 6f; 854 bri 6f;
855/* MS: Return to kernel state. */ 855/* MS: Return to kernel state. */
8562: VM_OFF /* MS: turn off MMU */ 8562:
857#ifdef CONFIG_PREEMPT
858 add r11, r0, CURRENT_TASK;
859 lwi r11, r11, TS_THREAD_INFO;
860 /* MS: get preempt_count from thread info */
861 lwi r5, r11, TI_PREEMPT_COUNT;
862 bgti r5, restore;
863
864 lwi r5, r11, TI_FLAGS; /* get flags in thread info */
865 andi r5, r5, _TIF_NEED_RESCHED;
866 beqi r5, restore /* if zero jump over */
867
868preempt:
869 /* interrupts are off that's why I am calling preempt_chedule_irq */
870 bralid r15, preempt_schedule_irq
871 nop
872 add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
873 lwi r11, r11, TS_THREAD_INFO; /* get thread info */
874 lwi r5, r11, TI_FLAGS; /* get flags in thread info */
875 andi r5, r5, _TIF_NEED_RESCHED;
876 bnei r5, preempt /* if non zero jump to resched */
877restore:
878#endif
879 VM_OFF /* MS: turn off MMU */
857 tophys(r1,r1) 880 tophys(r1,r1)
858 lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */ 881 lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
859 lwi r4, r1, PTO + PT_R4; 882 lwi r4, r1, PTO + PT_R4;