diff options
author | Stuart Menefy <stuart.menefy@st.com> | 2006-11-20 21:16:57 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-12-05 20:45:38 -0500 |
commit | f0bc814cfbc212683c882e58b3d1afec6b3e3aa3 (patch) | |
tree | 8ad669003716a3c22fb43e9c2066dcc5e5e0ad2d /arch/sh/kernel/traps.c | |
parent | 53644087a607040a56d883df612b588814a56f11 (diff) |
sh: gcc4 support.
This fixes up the kernel for gcc4. The existing exception handlers
needed some wrapping for pt_regs access, acessing the registers
via a RELOC_HIDE() pointer.
The strcpy() issues popped up here too, so add -ffreestanding and
kill off the symbol export.
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/traps.c')
-rw-r--r-- | arch/sh/kernel/traps.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index f558748d7543..b52037bc1255 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c | |||
@@ -23,8 +23,8 @@ | |||
23 | 23 | ||
24 | #ifdef CONFIG_SH_KGDB | 24 | #ifdef CONFIG_SH_KGDB |
25 | #include <asm/kgdb.h> | 25 | #include <asm/kgdb.h> |
26 | #define CHK_REMOTE_DEBUG(regs) \ | 26 | #define CHK_REMOTE_DEBUG(regs) \ |
27 | { \ | 27 | { \ |
28 | if (kgdb_debug_hook && !user_mode(regs))\ | 28 | if (kgdb_debug_hook && !user_mode(regs))\ |
29 | (*kgdb_debug_hook)(regs); \ | 29 | (*kgdb_debug_hook)(regs); \ |
30 | } | 30 | } |
@@ -501,7 +501,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) | |||
501 | /* | 501 | /* |
502 | * Handle various address error exceptions | 502 | * Handle various address error exceptions |
503 | */ | 503 | */ |
504 | asmlinkage void do_address_error(struct pt_regs *regs, | 504 | asmlinkage void do_address_error(struct pt_regs *regs, |
505 | unsigned long writeaccess, | 505 | unsigned long writeaccess, |
506 | unsigned long address) | 506 | unsigned long address) |
507 | { | 507 | { |
@@ -588,7 +588,7 @@ int is_dsp_inst(struct pt_regs *regs) | |||
588 | { | 588 | { |
589 | unsigned short inst; | 589 | unsigned short inst; |
590 | 590 | ||
591 | /* | 591 | /* |
592 | * Safe guard if DSP mode is already enabled or we're lacking | 592 | * Safe guard if DSP mode is already enabled or we're lacking |
593 | * the DSP altogether. | 593 | * the DSP altogether. |
594 | */ | 594 | */ |
@@ -612,8 +612,9 @@ int is_dsp_inst(struct pt_regs *regs) | |||
612 | #ifdef CONFIG_CPU_SH2A | 612 | #ifdef CONFIG_CPU_SH2A |
613 | asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, | 613 | asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, |
614 | unsigned long r6, unsigned long r7, | 614 | unsigned long r6, unsigned long r7, |
615 | struct pt_regs regs) | 615 | struct pt_regs __regs) |
616 | { | 616 | { |
617 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
617 | siginfo_t info; | 618 | siginfo_t info; |
618 | 619 | ||
619 | current->thread.trap_no = r4; | 620 | current->thread.trap_no = r4; |
@@ -635,12 +636,13 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, | |||
635 | /* arch/sh/kernel/cpu/sh4/fpu.c */ | 636 | /* arch/sh/kernel/cpu/sh4/fpu.c */ |
636 | extern int do_fpu_inst(unsigned short, struct pt_regs *); | 637 | extern int do_fpu_inst(unsigned short, struct pt_regs *); |
637 | extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, | 638 | extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, |
638 | unsigned long r6, unsigned long r7, struct pt_regs regs); | 639 | unsigned long r6, unsigned long r7, struct pt_regs __regs); |
639 | 640 | ||
640 | asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | 641 | asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, |
641 | unsigned long r6, unsigned long r7, | 642 | unsigned long r6, unsigned long r7, |
642 | struct pt_regs regs) | 643 | struct pt_regs __regs) |
643 | { | 644 | { |
645 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
644 | unsigned long error_code; | 646 | unsigned long error_code; |
645 | struct task_struct *tsk = current; | 647 | struct task_struct *tsk = current; |
646 | 648 | ||
@@ -648,11 +650,11 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | |||
648 | unsigned short inst = 0; | 650 | unsigned short inst = 0; |
649 | int err; | 651 | int err; |
650 | 652 | ||
651 | get_user(inst, (unsigned short*)regs.pc); | 653 | get_user(inst, (unsigned short*)regs->pc); |
652 | 654 | ||
653 | err = do_fpu_inst(inst, ®s); | 655 | err = do_fpu_inst(inst, regs); |
654 | if (!err) { | 656 | if (!err) { |
655 | regs.pc += 2; | 657 | regs->pc += 2; |
656 | return; | 658 | return; |
657 | } | 659 | } |
658 | /* not a FPU inst. */ | 660 | /* not a FPU inst. */ |
@@ -660,9 +662,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | |||
660 | 662 | ||
661 | #ifdef CONFIG_SH_DSP | 663 | #ifdef CONFIG_SH_DSP |
662 | /* Check if it's a DSP instruction */ | 664 | /* Check if it's a DSP instruction */ |
663 | if (is_dsp_inst(®s)) { | 665 | if (is_dsp_inst(regs)) { |
664 | /* Enable DSP mode, and restart instruction. */ | 666 | /* Enable DSP mode, and restart instruction. */ |
665 | regs.sr |= SR_DSP; | 667 | regs->sr |= SR_DSP; |
666 | return; | 668 | return; |
667 | } | 669 | } |
668 | #endif | 670 | #endif |
@@ -672,9 +674,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | |||
672 | local_irq_enable(); | 674 | local_irq_enable(); |
673 | tsk->thread.error_code = error_code; | 675 | tsk->thread.error_code = error_code; |
674 | tsk->thread.trap_no = TRAP_RESERVED_INST; | 676 | tsk->thread.trap_no = TRAP_RESERVED_INST; |
675 | CHK_REMOTE_DEBUG(®s); | 677 | CHK_REMOTE_DEBUG(regs); |
676 | force_sig(SIGILL, tsk); | 678 | force_sig(SIGILL, tsk); |
677 | die_if_no_fixup("reserved instruction", ®s, error_code); | 679 | die_if_no_fixup("reserved instruction", regs, error_code); |
678 | } | 680 | } |
679 | 681 | ||
680 | #ifdef CONFIG_SH_FPU_EMU | 682 | #ifdef CONFIG_SH_FPU_EMU |
@@ -722,17 +724,18 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs) | |||
722 | 724 | ||
723 | asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, | 725 | asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, |
724 | unsigned long r6, unsigned long r7, | 726 | unsigned long r6, unsigned long r7, |
725 | struct pt_regs regs) | 727 | struct pt_regs __regs) |
726 | { | 728 | { |
729 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
727 | unsigned long error_code; | 730 | unsigned long error_code; |
728 | struct task_struct *tsk = current; | 731 | struct task_struct *tsk = current; |
729 | #ifdef CONFIG_SH_FPU_EMU | 732 | #ifdef CONFIG_SH_FPU_EMU |
730 | unsigned short inst = 0; | 733 | unsigned short inst = 0; |
731 | 734 | ||
732 | get_user(inst, (unsigned short *)regs.pc + 1); | 735 | get_user(inst, (unsigned short *)regs->pc + 1); |
733 | if (!do_fpu_inst(inst, ®s)) { | 736 | if (!do_fpu_inst(inst, regs)) { |
734 | get_user(inst, (unsigned short *)regs.pc); | 737 | get_user(inst, (unsigned short *)regs->pc); |
735 | if (!emulate_branch(inst, ®s)) | 738 | if (!emulate_branch(inst, regs)) |
736 | return; | 739 | return; |
737 | /* fault in branch.*/ | 740 | /* fault in branch.*/ |
738 | } | 741 | } |
@@ -744,19 +747,20 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, | |||
744 | local_irq_enable(); | 747 | local_irq_enable(); |
745 | tsk->thread.error_code = error_code; | 748 | tsk->thread.error_code = error_code; |
746 | tsk->thread.trap_no = TRAP_RESERVED_INST; | 749 | tsk->thread.trap_no = TRAP_RESERVED_INST; |
747 | CHK_REMOTE_DEBUG(®s); | 750 | CHK_REMOTE_DEBUG(regs); |
748 | force_sig(SIGILL, tsk); | 751 | force_sig(SIGILL, tsk); |
749 | die_if_no_fixup("illegal slot instruction", ®s, error_code); | 752 | die_if_no_fixup("illegal slot instruction", regs, error_code); |
750 | } | 753 | } |
751 | 754 | ||
752 | asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, | 755 | asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, |
753 | unsigned long r6, unsigned long r7, | 756 | unsigned long r6, unsigned long r7, |
754 | struct pt_regs regs) | 757 | struct pt_regs __regs) |
755 | { | 758 | { |
759 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
756 | long ex; | 760 | long ex; |
757 | 761 | ||
758 | lookup_exception_vector(ex); | 762 | lookup_exception_vector(ex); |
759 | die_if_kernel("exception", ®s, ex); | 763 | die_if_kernel("exception", regs, ex); |
760 | } | 764 | } |
761 | 765 | ||
762 | #if defined(CONFIG_SH_STANDARD_BIOS) | 766 | #if defined(CONFIG_SH_STANDARD_BIOS) |
@@ -809,7 +813,7 @@ void *set_exception_table_vec(unsigned int vec, void *handler) | |||
809 | 813 | ||
810 | extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, | 814 | extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, |
811 | unsigned long r6, unsigned long r7, | 815 | unsigned long r6, unsigned long r7, |
812 | struct pt_regs regs); | 816 | struct pt_regs __regs); |
813 | 817 | ||
814 | void __init trap_init(void) | 818 | void __init trap_init(void) |
815 | { | 819 | { |