Commit caeb59c8 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] H8/300: preempt support

From: Yoshinori Sato <ysato@users.sourceforge.jp>

- add preempt support
- add new syscalls
- code cleanup
parent 906355ca
...@@ -265,8 +265,8 @@ SYMBOL_NAME_LABEL(sys_call_table) ...@@ -265,8 +265,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_io_getevents) .long SYMBOL_NAME(sys_io_getevents)
.long SYMBOL_NAME(sys_io_submit) .long SYMBOL_NAME(sys_io_submit)
.long SYMBOL_NAME(sys_io_cancel) .long SYMBOL_NAME(sys_io_cancel)
.long SYMBOL_NAME(sys_ni_syscall) /* 250 */ /* sys_alloc_hugepages */ .long SYMBOL_NAME(sys_fadvise64) /* 250 */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_freec_hugepages */ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_exit_group) .long SYMBOL_NAME(sys_exit_group)
.long SYMBOL_NAME(sys_lookup_dcookie) .long SYMBOL_NAME(sys_lookup_dcookie)
.long SYMBOL_NAME(sys_epoll_create) .long SYMBOL_NAME(sys_epoll_create)
...@@ -287,36 +287,39 @@ SYMBOL_NAME_LABEL(sys_call_table) ...@@ -287,36 +287,39 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_fstatfs64) .long SYMBOL_NAME(sys_fstatfs64)
.long SYMBOL_NAME(sys_tgkill) /* 270 */ .long SYMBOL_NAME(sys_tgkill) /* 270 */
.long SYMBOL_NAME(sys_utimes) .long SYMBOL_NAME(sys_utimes)
.long SYMBOL_NAME(sys_fadvise64_64)
.long SYMBOL_NAME(sys_ni_syscall) /* sys_vserver */
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
.long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_ni_syscall)
.endr .endr
.macro call_sp addr
mov.l #SYMBOL_NAME(\addr),er6
bra SYMBOL_NAME(syscall_trampoline):8
.endm
SYMBOL_NAME_LABEL(sys_clone) SYMBOL_NAME_LABEL(sys_clone)
mov.l #SYMBOL_NAME(h8300_clone),er0 call_sp h8300_clone
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_sigsuspend) SYMBOL_NAME_LABEL(sys_sigsuspend)
mov.l #SYMBOL_NAME(do_sigsuspend),er0 call_sp do_sigsuspend
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_rt_sigsuspend) SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
mov.l #SYMBOL_NAME(do_rt_sigsuspend),er0 call_sp do_rt_sigsuspend
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_sigreturn) SYMBOL_NAME_LABEL(sys_sigreturn)
mov.l #SYMBOL_NAME(do_sigreturn),er0 call_sp do_sigreturn
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_rt_sigreturn) SYMBOL_NAME_LABEL(sys_rt_sigreturn)
mov.l #SYMBOL_NAME(do_rt_sigreturn),er0 call_sp do_rt_sigreturn
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_fork) SYMBOL_NAME_LABEL(sys_fork)
mov.l #SYMBOL_NAME(h8300_fork),er0 call_sp h8300_fork
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_vfork) SYMBOL_NAME_LABEL(sys_vfork)
mov.l #SYMBOL_NAME(h8300_vfork),er0 call_sp h8300_vfork
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(syscall_trampoline)
mov.l sp,er0
jmp @er6
...@@ -109,12 +109,10 @@ ...@@ -109,12 +109,10 @@
.globl SYMBOL_NAME(system_call) .globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception) .globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_fork) .globl SYMBOL_NAME(ret_from_fork)
.globl SYMBOL_NAME(ret_from_signal)
.globl SYMBOL_NAME(ret_from_interrupt) .globl SYMBOL_NAME(ret_from_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table) .globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
.globl SYMBOL_NAME(resume) .globl SYMBOL_NAME(resume)
.globl SYMBOL_NAME(syscall_trampoline)
.globl SYMBOL_NAME(interrupt_redirect_table) .globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(interrupt_entry) .globl SYMBOL_NAME(interrupt_entry)
.globl SYMBOL_NAME(system_call) .globl SYMBOL_NAME(system_call)
...@@ -173,7 +171,7 @@ SYMBOL_NAME_LABEL(interrupt_entry) ...@@ -173,7 +171,7 @@ SYMBOL_NAME_LABEL(interrupt_entry)
beq 1f beq 1f
jsr @SYMBOL_NAME(do_softirq) jsr @SYMBOL_NAME(do_softirq)
1: 1:
jmp @SYMBOL_NAME(ret_from_exception) jmp @SYMBOL_NAME(ret_from_interrupt)
SYMBOL_NAME_LABEL(system_call) SYMBOL_NAME_LABEL(system_call)
subs #4,sp /* dummy LVEC */ subs #4,sp /* dummy LVEC */
...@@ -205,11 +203,11 @@ SYMBOL_NAME_LABEL(system_call) ...@@ -205,11 +203,11 @@ SYMBOL_NAME_LABEL(system_call)
mov.l @(LER2:16,sp),er1 mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2 mov.l @(LER3:16,sp),er2
jsr @er4 jsr @er4
mov.l er0,@(LER0,sp) /* save the return value */ mov.l er0,@(LER0:16,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT) #if defined(CONFIG_SYSCALL_PRINT)
jsr @SYMBOL_NAME(syscall_print) jsr @SYMBOL_NAME(syscall_print)
#endif #endif
jmp @SYMBOL_NAME(ret_from_exception) bra SYMBOL_NAME(ret_from_exception):8
1: 1:
jsr SYMBOL_NAME(syscall_trace) jsr SYMBOL_NAME(syscall_trace)
mov.l @(LER1:16,sp),er0 mov.l @(LER1:16,sp),er0
...@@ -218,44 +216,66 @@ SYMBOL_NAME_LABEL(system_call) ...@@ -218,44 +216,66 @@ SYMBOL_NAME_LABEL(system_call)
jsr @er4 jsr @er4
mov.l er0,@(LER0:16,sp) /* save the return value */ mov.l er0,@(LER0:16,sp) /* save the return value */
jsr @SYMBOL_NAME(syscall_trace) jsr @SYMBOL_NAME(syscall_trace)
bra SYMBOL_NAME(ret_from_exception):8
SYMBOL_NAME_LABEL(ret_from_signal) SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
bra SYMBOL_NAME(ret_from_exception):8
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
jsr @SYMBOL_NAME(set_esp0)
jsr @SYMBOL_NAME(schedule)
SYMBOL_NAME_LABEL(ret_from_exception) SYMBOL_NAME_LABEL(ret_from_exception)
#if defined(CONFIG_PREEMPT)
orc #0x80,ccr
#endif
SYMBOL_NAME_LABEL(ret_from_interrupt)
mov.b @(LCCR+1:16,sp),r0l mov.b @(LCCR+1:16,sp),r0l
btst #4,r0l /* check if returning to kernel */ btst #4,r0l /* check if returning to kernel */
bne 3f /* if so, skip resched, signals */ bne done:8 /* if so, skip resched, signals */
andc #0x7f,ccr andc #0x7f,ccr
mov.l sp,er2 mov.l sp,er4
and.w #0xe000,r2 and.w #0xe000,r4
mov.l @(TI_FLAGS:16,er2),er1 mov.l @(TI_FLAGS:16,er4),er1
and.l #_TIF_WORK_MASK,er1 and.l #_TIF_WORK_MASK,er1
beq 3f beq done:8
1: 1:
mov.l @(TI_FLAGS:16,er2),er1 mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l btst #TIF_NEED_RESCHED,r1l
bne SYMBOL_NAME(reschedule):16 bne SYMBOL_NAME(reschedule):16
mov.l sp,er1 mov.l sp,er1
subs #4,er1 /* adjust retpc */ subs #4,er1 /* adjust retpc */
mov.l er2,er0 mov.l er2,er0
jsr @SYMBOL_NAME(do_signal) jsr @SYMBOL_NAME(do_signal)
#if defined(CONFIG_PREEMPT)
bra done:8 /* userspace thoru */
3: 3:
btst #4,r0l
beq done:8 /* userspace thoru */
4:
mov.l @(TI_PRE_COUNT:16,er4),er1
bne done:8
mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l
beq done:8
mov.b r0l,r0l
bpl done:8 /* interrupt off (exception path?) */
mov.l #PREEMPT_ACTIVE,er1
mov.l er1,@(TI_PRE_COUNT:16,er4)
andc #0x7f,ccr
jsr @SYMBOL_NAME(schedule)
sub.l er1,er1
mov.l er1,@(TI_PRE_COUNT:16,er4)
orc #0x80,ccr
bra 4b:8
#endif
done:
RESTORE_ALL /* Does RTE */ RESTORE_ALL /* Does RTE */
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
jsr @SYMBOL_NAME(set_esp0)
mov.l #SYMBOL_NAME(ret_from_exception),er0
mov.l er0,@-sp
jmp @SYMBOL_NAME(schedule)
SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(resume) SYMBOL_NAME_LABEL(resume)
/* /*
* Beware - when entering resume, offset of tss is in d1, * Beware - when entering resume, offset of tss is in d1,
...@@ -306,11 +326,6 @@ SYMBOL_NAME_LABEL(trace_break) ...@@ -306,11 +326,6 @@ SYMBOL_NAME_LABEL(trace_break)
jsr @SYMBOL_NAME(trace_trap) jsr @SYMBOL_NAME(trace_trap)
jmp @SYMBOL_NAME(ret_from_exception) jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(syscall_trampoline)
mov.l er0,er6
mov.l sp,er0
jmp @er6
.section .bss .section .bss
SYMBOL_NAME_LABEL(sw_ksp) SYMBOL_NAME_LABEL(sw_ksp)
.space 4 .space 4
......
...@@ -109,12 +109,10 @@ ...@@ -109,12 +109,10 @@
.globl SYMBOL_NAME(system_call) .globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception) .globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_fork) .globl SYMBOL_NAME(ret_from_fork)
.globl SYMBOL_NAME(ret_from_signal)
.globl SYMBOL_NAME(ret_from_interrupt) .globl SYMBOL_NAME(ret_from_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table) .globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
.globl SYMBOL_NAME(resume) .globl SYMBOL_NAME(resume)
.globl SYMBOL_NAME(syscall_trampoline)
.globl SYMBOL_NAME(trace_break) .globl SYMBOL_NAME(trace_break)
.globl SYMBOL_NAME(interrupt_entry) .globl SYMBOL_NAME(interrupt_entry)
...@@ -201,11 +199,11 @@ SYMBOL_NAME_LABEL(system_call) ...@@ -201,11 +199,11 @@ SYMBOL_NAME_LABEL(system_call)
mov.l @(LER2:16,sp),er1 mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2 mov.l @(LER3:16,sp),er2
jsr @er4 jsr @er4
mov.l er0,@(LER0,sp) /* save the return value */ mov.l er0,@(LER0:16,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT) #if defined(CONFIG_SYSCALL_PRINT)
jsr @SYMBOL_NAME(syscall_print) jsr @SYMBOL_NAME(syscall_print)
#endif #endif
jmp @SYMBOL_NAME(ret_from_exception) bra SYMBOL_NAME(ret_from_exception):8
1: 1:
jsr SYMBOL_NAME(syscall_trace) jsr SYMBOL_NAME(syscall_trace)
mov.l @(LER1:16,sp),er0 mov.l @(LER1:16,sp),er0
...@@ -214,45 +212,67 @@ SYMBOL_NAME_LABEL(system_call) ...@@ -214,45 +212,67 @@ SYMBOL_NAME_LABEL(system_call)
jsr @er4 jsr @er4
mov.l er0,@(LER0:16,sp) /* save the return value */ mov.l er0,@(LER0:16,sp) /* save the return value */
jsr @SYMBOL_NAME(syscall_trace) jsr @SYMBOL_NAME(syscall_trace)
bra SYMBOL_NAME(ret_from_exception):8
SYMBOL_NAME_LABEL(ret_from_signal) SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
bra SYMBOL_NAME(ret_from_exception):8
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
jsr @SYMBOL_NAME(set_esp0)
jsr @SYMBOL_NAME(schedule)
SYMBOL_NAME_LABEL(ret_from_exception) SYMBOL_NAME_LABEL(ret_from_exception)
#if defined(CONFIG_PREEMPT)
orc #0x80,ccr
#endif
SYMBOL_NAME_LABEL(ret_from_interrupt)
mov.b @(LCCR+1:16,sp),r0l mov.b @(LCCR+1:16,sp),r0l
btst #4,r0l /* check if returning to kernel */ btst #4,r0l /* check if returning to kernel */
bne 3f /* if so, skip resched, signals */ bne done:8 /* if so, skip resched, signals */
andc #0x7f,ccr andc #0x7f,ccr
mov.l sp,er2 mov.l sp,er4
and.w #0xe000,r2 and.w #0xe000,r4
mov.l @(TI_FLAGS:16,er2),er1 mov.l @(TI_FLAGS:16,er4),er1
and.l #_TIF_WORK_MASK,er1 and.l #_TIF_WORK_MASK,er1
beq 3f beq done:8
1: 1:
mov.l @(TI_FLAGS:16,er2),er1 mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l btst #TIF_NEED_RESCHED,r1l
bne SYMBOL_NAME(reschedule):16 bne SYMBOL_NAME(reschedule):16
mov.l sp,er1 mov.l sp,er1
subs #4,er1 /* adjust retpc */ subs #4,er1 /* adjust retpc */
mov.l er2,er0 mov.l er2,er0
jsr @SYMBOL_NAME(do_signal) jsr @SYMBOL_NAME(do_signal)
#if defined(CONFIG_PREEMPT)
bra done:8 /* userspace thoru */
3: 3:
btst #4,r0l
beq done:8 /* userspace thoru */
4:
mov.l @(TI_PRE_COUNT:16,er4),er1
bne done:8
mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l
beq done:8
mov.b r0l,r0l
bpl done:8 /* interrupt off (exception path?) */
mov.l #PREEMPT_ACTIVE,er1
mov.l er1,@(TI_PRE_COUNT:16,er4)
andc #0x7f,ccr
jsr @SYMBOL_NAME(schedule)
sub.l er1,er1
mov.l er1,@(TI_PRE_COUNT:16,er4)
orc #0x80,ccr
bra 4b:8
#endif
done:
RESTORE_ALL /* Does RTE */ RESTORE_ALL /* Does RTE */
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
jsr @SYMBOL_NAME(set_esp0)
mov.l #SYMBOL_NAME(ret_from_exception),er0
mov.l er0,@-sp
jmp @SYMBOL_NAME(schedule)
SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(resume) SYMBOL_NAME_LABEL(resume)
/* /*
* er0 = prev * er0 = prev
...@@ -304,11 +324,6 @@ SYMBOL_NAME_LABEL(trace_break) ...@@ -304,11 +324,6 @@ SYMBOL_NAME_LABEL(trace_break)
jsr @SYMBOL_NAME(trace_trap) jsr @SYMBOL_NAME(trace_trap)
jmp @SYMBOL_NAME(ret_from_exception) jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(syscall_trampoline)
mov.l er0,er6
mov.l sp,er0
jmp @er6
.section .bss .section .bss
SYMBOL_NAME_LABEL(sw_ksp) SYMBOL_NAME_LABEL(sw_ksp)
.space 4 .space 4
......
...@@ -75,7 +75,7 @@ typedef struct { ...@@ -75,7 +75,7 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
# define in_atomic() (preempt_count() != kernel_locked()) # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else #else
# define in_atomic() (preempt_count() != 0) # define in_atomic() (preempt_count() != 0)
......
...@@ -32,10 +32,11 @@ struct thread_info { ...@@ -32,10 +32,11 @@ struct thread_info {
*/ */
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
task: &tsk, \ .task = &tsk, \
exec_domain: &default_exec_domain, \ .exec_domain = &default_exec_domain, \
flags: 0, \ .flags = 0, \
cpu: 0, \ .cpu = 0, \
.preempt_count = 1, \
.restart_block = { \ .restart_block = { \
.fn = do_no_restart_syscall, \ .fn = do_no_restart_syscall, \
}, \ }, \
...@@ -59,7 +60,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -59,7 +60,7 @@ static inline struct thread_info *current_thread_info(void)
"mov.l sp, %0 \n\t" "mov.l sp, %0 \n\t"
"and.l %1, %0" "and.l %1, %0"
: "=&r"(ti) : "=&r"(ti)
: "g" (~(THREAD_SIZE-1)) : "i" (~(THREAD_SIZE-1))
); );
return ti; return ti;
} }
...@@ -79,6 +80,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -79,6 +80,7 @@ static inline struct thread_info *current_thread_info(void)
#define TI_EXECDOMAIN 4 #define TI_EXECDOMAIN 4
#define TI_FLAGS 8 #define TI_FLAGS 8
#define TI_CPU 12 #define TI_CPU 12
#define TI_PRE_COUNT 16
#define PREEMPT_ACTIVE 0x4000000 #define PREEMPT_ACTIVE 0x4000000
......
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