diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-19 04:00:00 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-19 04:00:00 +0000 |
commit | 46e045034336a2cc90c1798cd7cc07af744ddfd6 (patch) | |
tree | 3b9b51fc482e729f663d25333e77fbed9aaa939a /arch/sh | |
parent | 31dc59d503a02e84c4de98826452acaeb56dc15a (diff) |
Merge with Linux 2.3.99-pre4.
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/config.in | 5 | ||||
-rw-r--r-- | arch/sh/defconfig | 2 | ||||
-rw-r--r-- | arch/sh/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/sh/kernel/entry.S | 556 | ||||
-rw-r--r-- | arch/sh/kernel/fpu.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/head.S | 9 | ||||
-rw-r--r-- | arch/sh/kernel/irq.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/irq_imask.c | 39 | ||||
-rw-r--r-- | arch/sh/kernel/process.c | 35 | ||||
-rw-r--r-- | arch/sh/kernel/ptrace.c | 595 | ||||
-rw-r--r-- | arch/sh/kernel/signal.c | 77 | ||||
-rw-r--r-- | arch/sh/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/mm/cache.c | 83 | ||||
-rw-r--r-- | arch/sh/mm/fault.c | 27 | ||||
-rw-r--r-- | arch/sh/mm/init.c | 2 |
16 files changed, 706 insertions, 744 deletions
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 83591c86c..1857ef33b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.2 1999/12/23 12:13:53 gniibe Exp gniibe $ +# $Id: Makefile,v 1.4 2000/03/08 15:14:14 gniibe Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive diff --git a/arch/sh/config.in b/arch/sh/config.in index e3bfd113c..2ee913c3c 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -48,6 +48,7 @@ mainmenu_option next_comment comment 'General setup' define_bool CONFIG_ISA n +define_bool CONFIG_SBUS n bool 'Networking support' CONFIG_NET @@ -73,6 +74,8 @@ bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG if [ "$CONFIG_HOTPLUG" = "y" ] ; then source drivers/pcmcia/Config.in +else + define_bool CONFIG_PCMCIA n fi bool 'System V IPC' CONFIG_SYSVIPC @@ -170,8 +173,6 @@ if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then source drivers/char/pcmcia/Config.in fi -#source drivers/misc/Config.in - source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then diff --git a/arch/sh/defconfig b/arch/sh/defconfig index fad2ab8b1..337e46956 100644 --- a/arch/sh/defconfig +++ b/arch/sh/defconfig @@ -29,10 +29,12 @@ CONFIG_MEMORY_START=0c000000 # General setup # # CONFIG_ISA is not set +# CONFIG_SBUS is not set # CONFIG_NET is not set CONFIG_CF_ENABLER=y # CONFIG_PCI is not set # CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_SYSCTL is not set diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index efa2fb109..8996a13dc 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -7,7 +7,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o irq_onchip.o \ @@ -29,7 +29,7 @@ all: kernel.o head.o init_task.o entry.o: entry.S head.o: head.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o + $(CC) $(AFLAGS) -traditional -c $*.S -o $*.o clean: diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 77bb7938b..46ad20f53 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.55 2000/03/05 01:48:58 gniibe Exp $ +/* $Id: entry.S,v 1.71 2000/03/22 13:29:33 gniibe Exp $ * * linux/arch/sh/entry.S * @@ -33,10 +33,9 @@ * * syscall # * ssr - * r15 = stack pointer * r0 * ... - * r14 + * r15 = stack pointer * gbr * mach * macl @@ -46,7 +45,7 @@ */ /* - * these are offsets into the task-struct. + * These are offsets into the task-struct. */ state = 0 flags = 4 @@ -78,8 +77,8 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register /* Offsets to the stack */ SYSCALL_NR = 0 SR = 4 -SP = 8 -R0 = 12 +R0 = 8 +SP = (8+15*4) #define k0 r0 #define k1 r1 @@ -96,7 +95,7 @@ R0 = 12 k2 scratch (Exception code) k3 scratch (Return address) k4 Stack base = current+8192 - k5 reserved + k5 Global Interrupt Mask (0--15) k6 reserved k7 reserved */ @@ -115,109 +114,113 @@ R0 = 12 ! this first version depends *much* on C implementation. ! -#define DO_FAULT(write) \ - mov.l 4f,r0; \ - mov.l @r0,r6; \ - /* STI */ \ - mov.l 3f,r1; \ - stc sr,r0; \ - and r1,r0; \ - ldc r0,sr; \ - /* */ \ - mov r15,r4; \ - mov.l 2f,r0; \ - jmp @r0; \ - mov #write,r5; +#define RESTORE_FLAGS() \ + mov.l @(SR,$r15), $r0; \ + and #0xf0, $r0; \ + shlr8 $r0; \ + cmp/eq #0x0f, $r0; \ + bt 9f; \ + mov.l __INV_IMASK, $r1; \ + stc $sr, $r0; \ + and $r1, $r0; \ + stc $r5_bank, $r1; \ + or $r1, $r0; \ + ldc $r0, $sr .balign 4 tlb_protection_violation_load: tlb_miss_load: - mov #-1,r0 - mov.l r0,@r15 ! syscall nr = -1 - DO_FAULT(0) + mov #-1, $r0 + mov.l $r0, @$r15 ! syscall nr = -1 + mov.l 2f, $r0 + mov.l @$r0, $r6 + RESTORE_FLAGS() +9: mov $r15, $r4 + mov.l 1f, $r0 + jmp @$r0 + mov #0, $r5 .balign 4 tlb_protection_violation_store: tlb_miss_store: initial_page_write: - mov #-1,r0 - mov.l r0,@r15 ! syscall nr = -1 - DO_FAULT(1) + mov #-1, $r0 + mov.l $r0, @$r15 ! syscall nr = -1 + mov.l 2f, $r0 + mov.l @$r0, $r6 + RESTORE_FLAGS() +9: mov $r15, $r4 + mov.l 1f, $r0 + jmp @$r0 + mov #1, $r5 .balign 4 -2: .long SYMBOL_NAME(do_page_fault) -3: .long 0xefffffff ! BL=0 -4: .long MMU_TEA +1: .long SYMBOL_NAME(do_page_fault) +2: .long MMU_TEA #ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB .balign 4 /* Unwind the stack and jmp to the debug entry */ debug: - add #4,r15 ! skip syscall number - mov.l @r15+,r11 ! SSR - mov.l @r15+,r10 ! original stack - mov.l @r15+,r0 - mov.l @r15+,r1 - mov.l @r15+,r2 - mov.l @r15+,r3 - mov.l @r15+,r4 - mov.l @r15+,r5 - mov.l @r15+,r6 - mov.l @r15+,r7 - stc sr,r14 - mov.l 8f,r9 ! BL =1, RB=1 - or r9,r14 - ldc r14,sr ! here, change the register bank - mov r10,k0 - mov r11,k1 - mov.l @r15+,r8 - mov.l @r15+,r9 - mov.l @r15+,r10 - mov.l @r15+,r11 - mov.l @r15+,r12 - mov.l @r15+,r13 - mov.l @r15+,r14 - ldc.l @r15+,gbr - lds.l @r15+,mach - lds.l @r15+,macl - lds.l @r15+,pr - ldc.l @r15+,spc - mov k0,r15 + add #4, $r15 ! skip syscall number + mov.l @$r15+, $r11 ! SSR + mov.l @$r15+, $r0 + mov.l @$r15+, $r1 + mov.l @$r15+, $r2 + mov.l @$r15+, $r3 + mov.l @$r15+, $r4 + mov.l @$r15+, $r5 + mov.l @$r15+, $r6 + mov.l @$r15+, $r7 + stc $sr, $r14 + mov.l 1f, $r9 ! BL =1, RB=1 + or $r9, $r14 + ldc $r14, $sr ! here, change the register bank + mov $r11, $k1 + mov.l @$r15+, $r8 + mov.l @$r15+, $r9 + mov.l @$r15+, $r10 + mov.l @$r15+, $r11 + mov.l @$r15+, $r12 + mov.l @$r15+, $r13 + mov.l @$r15+, $r14 + mov.l @$r15+, $k0 + ldc.l @$r15+, $gbr + lds.l @$r15+, $mach + lds.l @$r15+, $macl + lds.l @$r15+, $pr + ldc.l @$r15+, $spc + mov $k0, $r15 ! - mov.l 9f,k0 - jmp @k0 - ldc k1,ssr + mov.l 2f, $k0 + jmp @$k0 + ldc $k1, $ssr .balign 4 -8: .long 0x300000f0 -9: .long 0xa0000100 +1: .long 0x300000f0 +2: .long 0xa0000100 #endif .balign 4 error: - ! STI - mov.l 2f,r1 - stc sr,r0 - and r1,r0 - ldc r0,sr ! - mov.l 1f,r1 - mov #-1,r0 - jmp @r1 - mov.l r0,@r15 ! syscall nr = -1 + RESTORE_FLAGS() +9: mov.l 1f, $r1 + mov #-1, $r0 + jmp @$r1 + mov.l $r0, @$r15 ! syscall nr = -1 .balign 4 1: .long SYMBOL_NAME(do_exception_error) -2: .long 0xefffffff ! BL=0 -badsys: mov #-ENOSYS,r0 +badsys: mov #-ENOSYS, $r0 rts ! go to ret_from_syscall.. - mov.l r0,@(R0,r15) + mov.l $r0, @(R0,$r15) ! ! ! ENTRY(ret_from_fork) bra SYMBOL_NAME(ret_from_syscall) - add #4,r15 ! pop down bogus r0 (see switch_to MACRO) + add #4, $r15 ! pop down bogus r0 (see switch_to MACRO) ! ! The immediate value of "trapa" indicates the number of arguments @@ -226,83 +229,77 @@ ENTRY(ret_from_fork) ! Note that TRA register contains the value = Imm x 4. ! system_call: - mov.l 1f,r2 - mov.l @r2,r8 + mov.l 1f, $r2 + mov.l @$r2, $r8 ! ! DEBUG DEBUG - ! mov.l led,r1 - ! mov r0,r2 - ! mov.b r2,@r1 + ! mov.l led, $r1 + ! mov $r0, $r2 + ! mov.b $r2, @$r1 ! #ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB - mov #0x20,r1 - extu.b r1,r1 - shll2 r1 - cmp/hs r1,r8 + mov #0x20, $r1 + extu.b $r1, $r1 + shll2 $r1 + cmp/hs $r1, $r8 bt debug #endif - ! STI - mov.l 2f,r1 - stc sr,r2 - and r1,r2 - ldc r2,sr ! - mov.l __n_sys,r1 - cmp/hs r1,r0 - bt/s badsys - mov r0,r2 + mov $r0, $r2 + RESTORE_FLAGS() +9: mov.l __n_sys, $r1 + cmp/hs $r1, $r2 + bt badsys ! - stc ksp,r1 ! - mov.l __tsk_flags,r0 ! - add r0,r1 ! - mov.l @r1,r0 ! Is it trace? - tst #PF_TRACESYS,r0 + stc $ksp, $r1 + mov.l __tsk_flags, $r0 + add $r0, $r1 ! + mov.l @$r1, $r0 ! Is it trace? + tst #PF_TRACESYS, $r0 bt 5f ! Trace system call - mov #-ENOSYS,r1 - mov.l r1,@(R0,r15) - mov.l 3f,r1 - jsr @r1 + mov #-ENOSYS, $r1 + mov.l $r1, @(R0,$r15) + mov.l 3f, $r1 + jsr @$r1 nop - mova 4f,r0 + mova 3f, $r0 bra 6f - lds r0,pr - ! -5: mova ret,r0 ! normal case - lds r0,pr - ! Build the stack frame if TRA > 0 + lds $r0, $pr ! -6: mov r2,r3 - mov r8,r2 - cmp/pl r8 - bf 9f - mov.l @(SP,r15),r0 ! get original stack -7: add #-4,r8 -8: mov.l @(r0,r8),r1 ! May cause address error exception.. - mov.l r1,@-r15 - cmp/pl r8 +5: mova syscall_ret, $r0 + lds $r0, $pr + ! Build the stack frame if TRA > 0 +6: mov $r2, $r3 + mov $r8, $r2 + cmp/pl $r8 + bf 0f + mov #SP, $r0 + mov.l @($r0,$r15), $r0 ! get original stack +7: add #-4, $r8 +4: mov.l @($r0,$r8), $r1 ! May cause address error exception.. + mov.l $r1, @-$r15 + cmp/pl $r8 bt 7b ! -9: mov r3,r0 - shll2 r0 ! x4 - mov.l __sct,r1 - add r1,r0 - mov.l @r0,r1 - jmp @r1 - mov r2,r8 - +0: mov $r3, $r0 + shll2 $r0 ! x4 + mov.l __sct, $r1 + add $r1, $r0 + mov.l @$r0, $r1 + jmp @$r1 + mov $r2, $r8 ! In case of trace .balign 4 -4: add r8,r15 ! pop off the arguments - mov.l r0,@(R0,r15) ! save the return value - mov.l 3f,r1 - mova SYMBOL_NAME(ret_from_syscall),r0 - jmp @r1 - lds r0,pr +3: add $r8, $r15 ! pop off the arguments + mov.l $r0, @(R0,$r15) ! save the return value + mov.l 2f, $r1 + mova SYMBOL_NAME(ret_from_syscall), $r0 + jmp @$r1 + lds $r0, $pr .balign 4 -3: .long SYMBOL_NAME(syscall_trace) -2: .long 0xefffffff ! BL=0 1: .long TRA +2: .long SYMBOL_NAME(syscall_trace) __n_sys: .long NR_syscalls __sct: .long SYMBOL_NAME(sys_call_table) __tsk_flags: .long flags-8192 ! offset from stackbase to tsk->flags @@ -311,85 +308,80 @@ led: .long 0xa8000000 ! For my board -- gN .section .fixup,"ax" fixup_syscall_argerr: rts - mov.l 1f,r0 + mov.l 1f, $r0 1: .long -22 ! -EINVAL .previous .section __ex_table, "a" .balign 4 - .long 8b,fixup_syscall_argerr + .long 4b,fixup_syscall_argerr .previous + .balign 4 reschedule: - mova SYMBOL_NAME(ret_from_syscall),r0 - mov.l 1f,r1 - jmp @r1 - lds r0,pr + mova SYMBOL_NAME(ret_from_syscall), $r0 + mov.l 1f, $r1 + jmp @$r1 + lds $r0, $pr .balign 4 1: .long SYMBOL_NAME(schedule) ENTRY(ret_from_irq) - mov.l @(SR,r15),r0 ! get status register - shll r0 - shll r0 ! kernel space? + mov.l @(SR,$r15), $r0 ! get status register + shll $r0 + shll $r0 ! kernel space? bt restore_all ! Yes, it's from kernel, go back soon - ! STI - mov.l 1f, $r1 - stc $sr, $r2 - and $r1, $r2 - ldc $r2, $sr ! - bra ret_with_reschedule + RESTORE_FLAGS() +9: bra ret_with_reschedule nop ENTRY(ret_from_exception) - mov.l @(SR,r15),r0 ! get status register - shll r0 - shll r0 ! kernel space? + mov.l @(SR,$r15), $r0 ! get status register + shll $r0 + shll $r0 ! kernel space? bt restore_all ! Yes, it's from kernel, go back soon - ! STI - mov.l 1f, $r1 - stc $sr, $r2 - and $r1, $r2 - ldc $r2, $sr ! - bra ret_from_syscall + RESTORE_FLAGS() +9: bra ret_from_syscall nop .balign 4 -1: .long 0xefffffff ! BL=0 +__INV_IMASK: + .long 0xffffff0f ! ~(IMASK) .balign 4 -ret: add r8,r15 ! pop off the arguments - mov.l r0,@(R0,r15) ! save the return value +syscall_ret: + add $r8, $r15 ! pop off the arguments + mov.l $r0, @(R0,$r15) ! save the return value /* fall through */ ENTRY(ret_from_syscall) - mov.l __softirq_state,r0 - mov.l @r0,r1 - mov.l @(4,r0),r2 - tst r2,r1 + mov.l __softirq_state, $r0 + mov.l @$r0, $r1 + mov.l @(4,$r0), $r2 + tst $r2, $r1 bt ret_with_reschedule handle_softirq: - mov.l __do_softirq,r0 - jsr @r0 + mov.l __do_softirq, $r0 + jsr @$r0 nop ret_with_reschedule: - stc ksp,r1 - mov.l __minus8192,r0 - add r0,r1 - mov.l @(need_resched,r1),r0 - tst #0xff,r0 + stc $ksp, $r1 + mov.l __minus8192, $r0 + add $r0, $r1 + mov.l @(need_resched,$r1), $r0 + tst #0xff, $r0 bf reschedule - mov.l @(sigpending,r1),r0 - tst #0xff,r0 + mov.l @(sigpending,$r1), $r0 + tst #0xff, $r0 bt restore_all signal_return: - mov r15,r4 - mov #0,r5 - mov.l __do_signal,r1 - mova restore_all,r0 - jmp @r1 - lds r0,pr + mov $r15, $r4 + mov #0, $r5 + mov.l __do_signal, $r1 + mova restore_all, $r0 + jmp @$r1 + lds $r0, $pr .balign 4 __do_signal: .long SYMBOL_NAME(do_signal) @@ -407,56 +399,57 @@ restore_all: jsr @$r1 stc $sr, $r4 #endif - add #4,r15 ! Skip syscall number - mov.l @r15+,r11 ! Got SSR into R11 + add #4, $r15 ! Skip syscall number + mov.l @$r15+, $r11 ! Got SSR into R11 #if defined(__SH4__) mov $r11, $r12 #endif ! - mov.l 1f,r1 - stc sr,r0 - and r1,r0 ! Get IMASK+FD - mov.l 2f,r1 - and r1,r11 - or r0,r11 ! Inherit the IMASK+FD value of SR + mov.l 1f, $r1 + stc $sr, $r0 + and $r1, $r0 ! Get FD + mov.l 2f, $r1 + and $r1, $r11 + or $r0, $r11 ! Inherit the FD value of SR + stc $r5_bank, $r0 + or $r0, $r11 ! Inherit the IMASK value ! - mov.l @r15+,r10 ! original stack - mov.l @r15+,r0 - mov.l @r15+,r1 - mov.l @r15+,r2 - mov.l @r15+,r3 - mov.l @r15+,r4 - mov.l @r15+,r5 - mov.l @r15+,r6 - mov.l @r15+,r7 - stc sr,r14 - mov.l __blrb_flags,r9 ! BL =1, RB=1 - or r9,r14 - ldc r14,sr ! here, change the register bank - mov r10,k0 - mov r11,k1 + mov.l @$r15+, $r0 + mov.l @$r15+, $r1 + mov.l @$r15+, $r2 + mov.l @$r15+, $r3 + mov.l @$r15+, $r4 + mov.l @$r15+, $r5 + mov.l @$r15+, $r6 + mov.l @$r15+, $r7 + stc $sr, $r14 + mov.l __blrb_flags, $r9 ! BL =1, RB=1 + or $r9, $r14 + ldc $r14, $sr ! here, change the register bank + mov $r11, $k1 #if defined(__SH4__) mov $r12, $k2 #endif - mov.l @r15+,r8 - mov.l @r15+,r9 - mov.l @r15+,r10 - mov.l @r15+,r11 - mov.l @r15+,r12 - mov.l @r15+,r13 - mov.l @r15+,r14 - ldc.l @r15+,gbr - lds.l @r15+,mach - lds.l @r15+,macl - lds.l @r15+,pr - ldc.l @r15+,spc - ldc k1,ssr + mov.l @$r15+, $r8 + mov.l @$r15+, $r9 + mov.l @$r15+, $r10 + mov.l @$r15+, $r11 + mov.l @$r15+, $r12 + mov.l @$r15+, $r13 + mov.l @$r15+, $r14 + mov.l @$r15+, $k0 ! original stack + ldc.l @$r15+, $gbr + lds.l @$r15+, $mach + lds.l @$r15+, $macl + lds.l @$r15+, $pr + ldc.l @$r15+, $spc + ldc $k1, $ssr #if defined(__SH4__) shll $k1 shll $k1 bf 9f ! user mode /* Kernel to kernel transition */ - mov.l 3f, $k1 + mov.l 1f, $k1 tst $k1, $k2 bf 9f ! it hadn't FPU ! Kernel to kernel and FPU was used @@ -496,7 +489,7 @@ restore_all: lds.l @$r15+, $fpul 9: #endif - mov k0,r15 + mov $k0, $r15 rte nop @@ -510,9 +503,8 @@ __init_task_flags: __PF_USEDFPU: .long PF_USEDFPU #endif -1: .long 0x000080f0 ! IMASK+FD +1: .long 0x00008000 ! FD 2: .long 0xffff7f0f ! ~(IMASK+FD) -3: .long 0x00008000 ! FD=1 ! Exception Vector Base ! @@ -524,10 +516,10 @@ ENTRY(vbr_base) ! .balign 256,0,256 general_exception: - mov.l 1f,k2 - mov.l 2f,k3 + mov.l 1f, $k2 + mov.l 2f, $k3 bra handle_exception - mov.l @k2,k2 + mov.l @$k2, $k2 .balign 4 2: .long SYMBOL_NAME(ret_from_exception) 1: .long EXPEVT @@ -535,17 +527,17 @@ general_exception: ! .balign 1024,0,1024 tlb_miss: - mov.l 1f,k2 - mov.l 4f,k3 + mov.l 1f, $k2 + mov.l 4f, $k3 bra handle_exception - mov.l @k2,k2 + mov.l @$k2, $k2 ! .balign 512,0,512 interrupt: - mov.l 2f,k2 - mov.l 3f,k3 + mov.l 2f, $k2 + mov.l 3f, $k3 bra handle_exception - mov.l @k2,k2 + mov.l @$k2, $k2 .balign 4 1: .long EXPEVT @@ -559,9 +551,9 @@ handle_exception: ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! - stc ssr,k0 ! from kernel space? - shll k0 ! Check MD bit (bit30) - shll k0 + stc $ssr, $k0 ! from kernel space? + shll $k0 ! Check MD bit (bit30) + shll $k0 #if defined(__SH4__) bf/s 8f ! it's from user to kernel transition mov $r15, $k0 ! save original stack to k0 @@ -569,6 +561,7 @@ handle_exception: mov.l 2f, $k1 stc $ssr, $k0 tst $k1, $k0 + mov.l 4f, $k1 bf/s 9f ! FPU is not used mov $r15, $k0 ! save original stack to k0 ! FPU is used, save FPU @@ -593,64 +586,63 @@ handle_exception: fmov.s $fr1, @-$r15 fmov.s $fr0, @-$r15 bra 9f - mov #0, $k1 + mov.l 3f, $k1 #else + mov.l 3f, $k1 bt/s 9f ! it's from kernel to kernel transition - mov r15,k0 ! save original stack to k0 anyway + mov $r15, $k0 ! save original stack to k0 anyway #endif 8: /* User space to kernel */ - mov kernel_sp, $r15 ! change to kernel stack -#if defined(__SH4__) - mov.l 2f, $k1 ! let kernel release FPU -#endif -9: stc.l spc,@-r15 - sts.l pr,@-r15 + mov $kernel_sp, $r15 ! change to kernel stack + mov.l 4f, $k1 ! let kernel release FPU +9: stc.l $spc, @-$r15 + sts.l $pr, @-$r15 ! - lds k3,pr ! Set the return address to pr + lds $k3, $pr ! Set the return address to pr ! - sts.l macl,@-r15 - sts.l mach,@-r15 - stc.l gbr,@-r15 - mov.l r14,@-r15 + sts.l $macl, @-$r15 + sts.l $mach, @-$r15 + stc.l $gbr, @-$r15 + mov.l $k0, @-$r15 ! save orignal stack + mov.l $r14, @-$r15 ! - stc sr,r14 ! Back to normal register bank, and -#if defined(__SH4__) - or $k1, $r14 ! may release FPU -#endif - mov.l 3f,k1 - and k1,r14 ! ... - ldc r14,sr ! ...changed here. + stc $sr, $r14 ! Back to normal register bank, and + or $k1, $r14 ! Block all interrupts, may release FPU + mov.l 5f, $k1 + and $k1, $r14 ! ... + ldc $r14, $sr ! ...changed here. ! - mov.l r13,@-r15 - mov.l r12,@-r15 - mov.l r11,@-r15 - mov.l r10,@-r15 - mov.l r9,@-r15 - mov.l r8,@-r15 - mov.l r7,@-r15 - mov.l r6,@-r15 - mov.l r5,@-r15 - mov.l r4,@-r15 - mov.l r3,@-r15 - mov.l r2,@-r15 - mov.l r1,@-r15 - mov.l r0,@-r15 - stc.l r0_bank,@-r15 ! save orignal stack - stc.l ssr,@-r15 - mov.l r0,@-r15 ! push r0 again (for syscall number) + mov.l $r13, @-$r15 + mov.l $r12, @-$r15 + mov.l $r11, @-$r15 + mov.l $r10, @-$r15 + mov.l $r9, @-$r15 + mov.l $r8, @-$r15 + mov.l $r7, @-$r15 + mov.l $r6, @-$r15 + mov.l $r5, @-$r15 + mov.l $r4, @-$r15 + mov.l $r3, @-$r15 + mov.l $r2, @-$r15 + mov.l $r1, @-$r15 + mov.l $r0, @-$r15 + stc.l $ssr, @-$r15 + mov.l $r0, @-$r15 ! push $r0 again (for syscall number) ! Then, dispatch to the handler, according to the excepiton code. - stc k_ex_code,r1 - shlr2 r1 - shlr r1 - mov.l 1f,r0 - add r1,r0 - mov.l @r0,r0 - jmp @r0 - mov.l @r15,r0 ! recovering r0.. + stc $k_ex_code, $r1 + shlr2 $r1 + shlr $r1 + mov.l 1f, $r0 + add $r1, $r0 + mov.l @$r0, $r0 + jmp @$r0 + mov.l @$r15, $r0 ! recovering $r0.. .balign 4 1: .long SYMBOL_NAME(exception_handling_table) 2: .long 0x00008000 ! FD=1 -3: .long 0xdfffffff ! RB=0, leave BL=1 +3: .long 0x000000f0 ! FD=0, IMASK=15 +4: .long 0x000080f0 ! FD=1, IMASK=15 +5: .long 0xcfffffff ! RB=0, BL=0 none: rts @@ -679,7 +671,7 @@ ENTRY(exception_handling_table) ENTRY(nmi_slot) .long none ! Not implemented yet ENTRY(user_break_point_trap) - .long error ! Not implemented yet + .long break_point_trap ENTRY(interrupt_table) ! external hardware .long SYMBOL_NAME(do_IRQ) ! 0000 @@ -985,6 +977,8 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_setfsuid) /* 215 */ .long SYMBOL_NAME(sys_setfsgid) .long SYMBOL_NAME(sys_pivot_root) + .long SYMBOL_NAME(sys_mincore) + .long SYMBOL_NAME(sys_madvise) /* * NOTE!! This doesn't have to be exact - we just have @@ -992,7 +986,7 @@ ENTRY(sys_call_table) * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-217 + .rept NR_syscalls-219 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/sh/kernel/fpu.c b/arch/sh/kernel/fpu.c index 335902c1d..5301a1333 100644 --- a/arch/sh/kernel/fpu.c +++ b/arch/sh/kernel/fpu.c @@ -1,4 +1,4 @@ -/* $Id: fpu.c,v 1.27 2000/03/05 01:48:34 gniibe Exp $ +/* $Id: fpu.c,v 1.29 2000/03/22 13:42:10 gniibe Exp $ * * linux/arch/sh/kernel/fpu.c * @@ -114,8 +114,6 @@ restore_fpu(struct task_struct *tsk) * has the property that no matter wether considered as single or as * double precission represents signaling NANS. */ -/* Double presision, NANS as NANS, rounding to nearest, no exceptions */ -#define FPU_DEFAULT 0x00080000 void fpu_init(void) { @@ -156,7 +154,7 @@ void fpu_init(void) "fsts $fpul, $fr15\n\t" "frchg" : /* no output */ - : "r" (0), "r" (FPU_DEFAULT)); + : "r" (0), "r" (FPSCR_INIT)); } asmlinkage void diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 3f938557a..ae406d22d 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.16 2000/03/02 00:01:15 gniibe Exp $ +/* $Id: head.S,v 1.17 2000/03/06 12:44:24 gniibe Exp $ * * arch/sh/kernel/head.S * @@ -37,8 +37,11 @@ ENTRY(empty_zero_page) */ ENTRY(_stext) ! Initialize Status Register - mov.l 1f, $r0 ! MD=1, RB=0, BL=1 + mov.l 1f, $r0 ! MD=1, RB=0, BL=0, IMASK=0xF ldc $r0, $sr + ! Initialize global interrupt mask + mov #0, $r0 + ldc $r0, $r5_bank ! mov.l 2f, $r0 mov $r0, $r15 ! Set initial r15 (stack pointer) @@ -62,7 +65,7 @@ ENTRY(_stext) nop .balign 4 -1: .long 0x50000000 ! MD=1, RB=0, BL=1, FD=0 +1: .long 0x400000F0 ! MD=1, RB=0, BL=0, FD=0, IMASK=0xF 2: .long SYMBOL_NAME(stack) 3: .long SYMBOL_NAME(__bss_start) 4: .long SYMBOL_NAME(_end) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index a15352389..af03ef46d 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.11 2000/02/29 11:03:40 gniibe Exp $ +/* $Id: irq.c,v 1.12 2000/03/06 14:07:50 gniibe Exp $ * * linux/arch/sh/kernel/irq.c * @@ -238,11 +238,11 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, regs.syscall_nr = -1; /* It's not system call */ /* Get IRQ number */ - asm volatile("stc r2_bank,%0\n\t" + asm volatile("stc $r2_bank, %0\n\t" "shlr2 %0\n\t" "shlr2 %0\n\t" "shlr %0\n\t" - "add #-16,%0\n\t" + "add #-16, %0\n\t" :"=z" (irq)); kstat.irqs[cpu][irq]++; diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c index a3cf78b5f..380acf405 100644 --- a/arch/sh/kernel/irq_imask.c +++ b/arch/sh/kernel/irq_imask.c @@ -1,8 +1,8 @@ -/* $Id: irq_imask.c,v 1.2 2000/02/11 04:57:40 gniibe Exp $ +/* $Id: irq_imask.c,v 1.6 2000/03/06 14:11:32 gniibe Exp $ * * linux/arch/sh/kernel/irq_imask.c * - * Copyright (C) 1999 Niibe Yutaka + * Copyright (C) 1999, 2000 Niibe Yutaka * * Simple interrupt handling using IMASK of SR register. * @@ -52,35 +52,40 @@ static struct hw_interrupt_type imask_irq_type = { end_imask_irq }; -void disable_imask_irq(unsigned int irq) +void static inline set_interrupt_registers(int ip) { unsigned long __dummy; + asm volatile("ldc %2, $r5_bank\n\t" + "stc $sr, %0\n\t" + "and #0xf0, %0\n\t" + "shlr8 %0\n\t" + "cmp/eq #0x0f, %0\n\t" + "bt 1f ! CLI-ed\n\t" + "stc $sr, %0\n\t" + "and %1, %0\n\t" + "or %2, %0\n\t" + "ldc %0, $sr\n" + "1:" + : "=&z" (__dummy) + : "r" (~0xf0), "r" (ip << 4)); +} + +void disable_imask_irq(unsigned int irq) +{ clear_bit(irq, &imask_mask); if (interrupt_priority < IMASK_PRIORITY - irq) interrupt_priority = IMASK_PRIORITY - irq; - asm volatile("stc sr,%0\n\t" - "and %1,%0\n\t" - "or %2,%0\n\t" - "ldc %0,sr" - : "=&r" (__dummy) - : "r" (0xffffff0f), "r" (interrupt_priority << 4)); + set_interrupt_registers(interrupt_priority); } static void enable_imask_irq(unsigned int irq) { - unsigned long __dummy; - set_bit(irq, &imask_mask); interrupt_priority = IMASK_PRIORITY - ffz(imask_mask); - asm volatile("stc sr,%0\n\t" - "and %1,%0\n\t" - "or %2,%0\n\t" - "ldc %0,sr" - : "=&r" (__dummy) - : "r" (0xffffff0f), "r" (interrupt_priority << 4)); + set_interrupt_registers(interrupt_priority); } static void mask_and_ack_imask(unsigned int irq) diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 2ca91cb40..97cd1fe0c 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.28 2000/03/05 02:16:15 gniibe Exp $ +/* $Id: process.c,v 1.33 2000/03/25 00:06:15 gniibe Exp $ * * linux/arch/sh/kernel/process.c * @@ -94,7 +94,7 @@ void show_regs(struct pt_regs * regs) { printk("\n"); printk("PC : %08lx SP : %08lx SR : %08lx TEA : %08lx\n", - regs->pc, regs->sp, regs->sr, ctrl_inl(MMU_TEA)); + regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA)); printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", regs->regs[0],regs->regs[1], regs->regs[2],regs->regs[3]); @@ -210,22 +210,22 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; +#if defined(__SH4__) struct task_struct *tsk = current; - childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1; - struct_cpy(childregs, regs); - -#if defined(__SH4__) if (tsk != &init_task) { unlazy_fpu(tsk); - struct_cpy(&p->thread.fpu, ¤t->thread.fpu); + p->thread.fpu = current->thread.fpu; p->used_math = tsk->used_math; } #endif + childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1; + *childregs = *regs; + if (user_mode(regs)) { - childregs->sp = usp; + childregs->regs[15] = usp; } else { - childregs->sp = (unsigned long)p+2*PAGE_SIZE; + childregs->regs[15] = (unsigned long)p+2*PAGE_SIZE; } childregs->regs[0] = 0; /* Set return value for child */ childregs->sr |= SR_FD; /* Invalidate FPU flag */ @@ -244,7 +244,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump) dump->magic = CMAGIC; dump->start_code = current->mm->start_code; dump->start_data = current->mm->start_data; - dump->start_stack = regs->sp & ~(PAGE_SIZE - 1); + dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1); dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT; dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT; dump->u_ssize = (current->mm->start_stack - dump->start_stack + @@ -279,7 +279,7 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(SIGCHLD, regs.sp, ®s); + return do_fork(SIGCHLD, regs.regs[15], ®s); } asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, @@ -287,7 +287,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs regs) { if (!newsp) - newsp = regs.sp; + newsp = regs.regs[15]; return do_fork(clone_flags, newsp, ®s); } @@ -305,7 +305,7 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, ®s); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s); } /* @@ -370,3 +370,12 @@ asmlinkage void print_syscall(int x) (init_task.flags&PF_USEDFPU)?'K':' ', (sr&SR_FD)?' ':'F'); restore_flags(flags); } + +asmlinkage void break_point_trap(void) +{ + /* Clear traicng. */ + ctrl_outw(0, UBC_BBRA); + ctrl_outw(0, UBC_BBRB); + + force_sig(SIGTRAP, current); +} diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 2d69b5b7c..d4a1556b9 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -1,6 +1,13 @@ -/* - * Surely this doesn't work... (we need to design ptrace for SupreH) +/* $Id: ptrace.c,v 1.4 2000/03/22 13:59:01 gniibe Exp $ + * * linux/arch/sh/kernel/ptrace.c + * + * Original x86 implementation: + * By Ross Biro 1/23/92 + * edited by Linus Torvalds + * + * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka + * */ #include <linux/kernel.h> @@ -12,135 +19,126 @@ #include <linux/ptrace.h> #include <linux/user.h> +#include <asm/io.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/system.h> #include <asm/processor.h> +#include <asm/mmu_context.h> /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ -#define FLAG_MASK 0x00044dd5 - -/* set's the trap flag. */ -#define TRAP_FLAG 0x100 - /* - * Offset of eflags on child stack.. + * This routine will get a word off of the process kernel stack. */ -#define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs)) - -/* - * this routine will get a word off of the processes privileged stack. - * the offset is how far from the base addr as stored in the TSS. - * this routine assumes that all the privileged stacks are in our - * data space. - */ static inline int get_stack_long(struct task_struct *task, int offset) { unsigned char *stack; - stack = (unsigned char *)task->thread.sp; + stack = (unsigned char *)task + THREAD_SIZE - sizeof(struct pt_regs); stack += offset; return (*((int *)stack)); } /* - * this routine will put a word on the processes privileged stack. - * the offset is how far from the base addr as stored in the TSS. - * this routine assumes that all the privileged stacks are in our - * data space. + * This routine will put a word on the process kernel stack. */ static inline int put_stack_long(struct task_struct *task, int offset, - unsigned long data) + unsigned long data) { - unsigned char * stack; + unsigned char *stack; - stack = (unsigned char *) task->thread.sp; + stack = (unsigned char *)task + THREAD_SIZE - sizeof(struct pt_regs); stack += offset; *(unsigned long *) stack = data; return 0; } -static int putreg(struct task_struct *child, - unsigned long regno, unsigned long value) +static void +compute_next_pc(struct pt_regs *regs, unsigned short inst, + unsigned long *pc1, unsigned long *pc2) { -#if 0 - switch (regno >> 2) { - case ORIG_EAX: - return -EIO; - case FS: - if (value && (value & 3) != 3) - return -EIO; - child->thread.fs = value; - return 0; - case GS: - if (value && (value & 3) != 3) - return -EIO; - child->thread.gs = value; - return 0; - case DS: - case ES: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case SS: - case CS: - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case EFL: - value &= FLAG_MASK; - value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; + int nib[4] + = { (inst >> 12) & 0xf, + (inst >> 8) & 0xf, + (inst >> 4) & 0xf, + inst & 0xf}; + + /* bra & bsr */ + if (nib[0] == 0xa || nib[0] == 0xb) { + *pc1 = regs->pc + 4 + ((short) ((inst & 0xfff) << 4) >> 3); + *pc2 = (unsigned long) -1; + return; } - if (regno > GS*4) - regno -= 2*4; - put_stack_long(child, regno - sizeof(struct pt_regs), value); -#endif - return 0; + + /* bt & bf */ + if (nib[0] == 0x8 && (nib[1] == 0x9 || nib[1] == 0xb)) { + *pc1 = regs->pc + 4 + ((char) (inst & 0xff) << 1); + *pc2 = regs->pc + 2; + return; + } + + /* bt/s & bf/s */ + if (nib[0] == 0x8 && (nib[1] == 0xd || nib[1] == 0xf)) { + *pc1 = regs->pc + 4 + ((char) (inst & 0xff) << 1); + *pc2 = regs->pc + 4; + return; + } + + /* jmp & jsr */ + if (nib[0] == 0x4 && nib[3] == 0xb + && (nib[2] == 0x0 || nib[2] == 0x2)) { + *pc1 = regs->regs[nib[1]]; + *pc2 = (unsigned long) -1; + return; + } + + /* braf & bsrf */ + if (nib[0] == 0x0 && nib[3] == 0x3 + && (nib[2] == 0x0 || nib[2] == 0x2)) { + *pc1 = regs->pc + 4 + regs->regs[nib[1]]; + *pc2 = (unsigned long) -1; + return; + } + + if (inst == 0x000b) { + *pc1 = regs->pr; + *pc2 = (unsigned long) -1; + return; + } + + *pc1 = regs->pc + 2; + *pc2 = (unsigned long) -1; + return; } -static unsigned long getreg(struct task_struct *child, - unsigned long regno) +/* Tracing by user break controller. */ +static void +ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2) { - unsigned long retval = ~0UL; - -#if 0 - switch (regno >> 2) { - case FS: - retval = child->thread.fs; - break; - case GS: - retval = child->thread.gs; - break; - case DS: - case ES: - case SS: - case CS: - retval = 0xffff; - /* fall through */ - default: - if (regno > GS*4) - regno -= 2*4; - regno = regno - sizeof(struct pt_regs); - retval &= get_stack_long(child, regno); + ctrl_outl(nextpc1, UBC_BARA); + ctrl_outb(asid, UBC_BASRA); + ctrl_outb(BAMR_12, UBC_BAMRA); + ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); + + if (nextpc2 != (unsigned long) -1) { + ctrl_outl(nextpc2, UBC_BARB); + ctrl_outb(asid, UBC_BASRB); + ctrl_outb(BAMR_12, UBC_BAMRB); + ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB); } -#endif - return retval; + ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR); } asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { - struct task_struct *child; + struct task_struct *child, *tsk = current; struct user * dummy = NULL; unsigned long flags; - int i, ret; + int ret; lock_kernel(); ret = -EPERM; @@ -163,16 +161,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (pid == 1) /* you may not mess with init */ goto out; if (request == PTRACE_ATTACH) { - if (child == current) + if (child == tsk) goto out; if ((!child->dumpable || - (current->uid != child->euid) || - (current->uid != child->suid) || - (current->uid != child->uid) || - (current->gid != child->egid) || - (current->gid != child->sgid) || - (!cap_issubset(child->cap_permitted, current->cap_permitted)) || - (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) + (tsk->uid != child->euid) || + (tsk->uid != child->suid) || + (tsk->uid != child->uid) || + (tsk->gid != child->egid) || + (tsk->gid != child->sgid) || + (!cap_issubset(child->cap_permitted, tsk->cap_permitted)) || + (tsk->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) goto out; /* the same process cannot be attached many times */ if (child->flags & PF_PTRACED) @@ -180,9 +178,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) child->flags |= PF_PTRACED; write_lock_irqsave(&tasklist_lock, flags); - if (child->p_pptr != current) { + if (child->p_pptr != tsk) { REMOVE_LINKS(child); - child->p_pptr = current; + child->p_pptr = tsk; SET_LINKS(child); } write_unlock_irqrestore(&tasklist_lock, flags); @@ -198,257 +196,180 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (request != PTRACE_KILL) goto out; } - if (child->p_pptr != current) + if (child->p_pptr != tsk) goto out; switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { - unsigned long tmp; - int copied; - - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - ret = -EIO; - if (copied != sizeof(tmp)) - goto out; - ret = put_user(tmp,(unsigned long *) data); - goto out; - } + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; + int copied; + + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + ret = -EIO; + if (copied != sizeof(tmp)) + break; + ret = put_user(tmp,(unsigned long *) data); + break; + } /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long tmp; - - ret = -EIO; - if ((addr & 3) || addr < 0 || - addr > sizeof(struct user) - 3) - goto out; - - tmp = 0; /* Default return condition */ - if(addr < 17*sizeof(long)) - tmp = getreg(child, addr); -#if 0 - if(addr >= (long) &dummy->u_debugreg[0] && - addr <= (long) &dummy->u_debugreg[7]){ - addr -= (long) &dummy->u_debugreg[0]; - addr = addr >> 2; - tmp = child->thread.debugreg[addr]; - }; -#endif - ret = put_user(tmp,(unsigned long *) data); - goto out; - } + case PTRACE_PEEKUSR: { + unsigned long tmp; - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = 0; - if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) - goto out; - ret = -EIO; - goto out; + ret = -EIO; + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + break; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = -EIO; - if ((addr & 3) || addr < 0 || - addr > sizeof(struct user) - 3) - goto out; - - if (addr < 17*sizeof(long)) { - ret = putreg(child, addr, data); - goto out; - } - - /* We need to be very careful here. We implicitly - want to modify a portion of the task_struct, and we - have to be selective about what portions we allow someone - to modify. */ -#if 0 - if(addr >= (long) &dummy->u_debugreg[0] && - addr <= (long) &dummy->u_debugreg[7]){ - - if(addr == (long) &dummy->u_debugreg[4]) return -EIO; - if(addr == (long) &dummy->u_debugreg[5]) return -EIO; - if(addr < (long) &dummy->u_debugreg[4] && - ((unsigned long) data) >= TASK_SIZE-3) return -EIO; - - ret = -EIO; - if(addr == (long) &dummy->u_debugreg[7]) { - data &= ~DR_CONTROL_RESERVED; - for(i=0; i<4; i++) - if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1) - goto out; - }; - - addr -= (long) &dummy->u_debugreg; - addr = addr >> 2; - child->thread.debugreg[addr] = data; - ret = 0; - goto out; - }; -#endif - ret = -EIO; - goto out; - - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - long tmp; - - ret = -EIO; - if ((unsigned long) data > _NSIG) - goto out; - if (request == PTRACE_SYSCALL) - child->flags |= PF_TRACESYS; - else - child->flags &= ~PF_TRACESYS; - child->exit_code = data; - /* make sure the single step bit is not set. */ -#if 0 - tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; - put_stack_long(child, EFL_OFFSET,tmp); -#endif - wake_up_process(child); + if (addr < sizeof(struct pt_regs)) + tmp = get_stack_long(child, addr); + else if (addr >= (long) &dummy->fpu && + addr < (long) &dummy->u_fpvalid) { + if (!child->used_math) { + if (addr == (long)&dummy->fpu.fpscr) + tmp = FPSCR_INIT; + else + tmp = 0; + } else + tmp = ((long *)&child->thread.fpu) + [(addr - (long)&dummy->fpu) >> 2]; + } else if (addr == (long) &dummy->u_fpvalid) + tmp = child->used_math; + else + tmp = 0; + ret = put_user(tmp, (unsigned long *)data); + break; + } + + /* when I and D space are separate, this will have to be fixed. */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + ret = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + break; + ret = -EIO; + break; + + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + ret = -EIO; + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + break; + + if (addr < sizeof(struct pt_regs)) + ret = put_stack_long(child, addr, data); + else if (addr >= (long) &dummy->fpu && + addr < (long) &dummy->u_fpvalid) { + child->used_math = 1; + ((long *)&child->thread.fpu) + [(addr - (long)&dummy->fpu) >> 2] = data; + ret = 0; + } else if (addr == (long) &dummy->u_fpvalid) { + child->used_math = data?1:0; ret = 0; - goto out; } + break; + + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + if (request == PTRACE_SYSCALL) + child->flags |= PF_TRACESYS; + else + child->flags &= ~PF_TRACESYS; + child->exit_code = data; + wake_up_process(child); + ret = 0; + break; + } /* * make the child exit. Best I can do is send it a sigkill. * perhaps it should be put in the status that it wants to * exit. */ - case PTRACE_KILL: { - long tmp; + case PTRACE_KILL: { + ret = 0; + if (child->state == TASK_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + wake_up_process(child); + break; + } - ret = 0; - if (child->state == TASK_ZOMBIE) /* already dead */ - goto out; - child->exit_code = SIGKILL; - /* make sure the single step bit is not set. */ -#if 0 - tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; - put_stack_long(child, EFL_OFFSET, tmp); -#endif - wake_up_process(child); - goto out; - } + case PTRACE_SINGLESTEP: { /* set the trap flag. */ + long tmp, pc; + struct pt_regs *dummy = NULL; + struct pt_regs *regs; + unsigned long nextpc1, nextpc2; + unsigned short insn; - case PTRACE_SINGLESTEP: { /* set the trap flag. */ - long tmp; + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->flags &= ~PF_TRACESYS; + if ((child->flags & PF_DTRACE) == 0) { + /* Spurious delayed TF traps may occur */ + child->flags |= PF_DTRACE; + } - ret = -EIO; - if ((unsigned long) data > _NSIG) - goto out; - child->flags &= ~PF_TRACESYS; - if ((child->flags & PF_DTRACE) == 0) { - /* Spurious delayed TF traps may occur */ - child->flags |= PF_DTRACE; - } -#if 0 - tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG; - put_stack_long(child, EFL_OFFSET, tmp); + /* Compute next pc. */ + pc = get_stack_long(child, (long)&dummy->pc); + regs = (struct pt_regs *)((unsigned long)child + THREAD_SIZE - sizeof(struct pt_regs)); + if (access_process_vm(child, pc&~3, &tmp, sizeof(tmp), 1) != sizeof(data)) + break; + +#ifdef __LITTLE_ENDIAN__ + if (pc & 3) + insn = tmp >> 16; + else + insn = tmp & 0xffff; +#else + if (pc & 3) + insn = tmp & 0xffff; + else + insn = tmp >> 16; #endif - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - goto out; - } + compute_next_pc (regs, insn, &nextpc1, &nextpc2); - case PTRACE_DETACH: { /* detach a process that was attached. */ - long tmp; + if (nextpc1 & 0x80000000) + break; + if (nextpc2 != (unsigned long) -1 && (nextpc2 & 0x80000000)) + break; - ret = -EIO; - if ((unsigned long) data > _NSIG) - goto out; - child->flags &= ~(PF_PTRACED|PF_TRACESYS); - child->exit_code = data; - write_lock_irqsave(&tasklist_lock, flags); - REMOVE_LINKS(child); - child->p_pptr = child->p_opptr; - SET_LINKS(child); - write_unlock_irqrestore(&tasklist_lock, flags); - /* make sure the single step bit is not set. */ -#if 0 - tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; - put_stack_long(child, EFL_OFFSET, tmp); -#endif - wake_up_process(child); - ret = 0; - goto out; - } -#if 0 - case PTRACE_GETREGS: { /* Get all gp regs from the child. */ - if (!access_ok(VERIFY_WRITE, (unsigned *)data, - 17*sizeof(long))) - { - ret = -EIO; - goto out; - } - for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) - { - __put_user(getreg(child, i),(unsigned long *) data); - data += sizeof(long); - } - ret = 0; - goto out; - }; - - case PTRACE_SETREGS: { /* Set all gp regs in the child. */ - unsigned long tmp; - if (!access_ok(VERIFY_READ, (unsigned *)data, - 17*sizeof(long))) - { - ret = -EIO; - goto out; - } - for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) - { - __get_user(tmp, (unsigned long *) data); - putreg(child, i, tmp); - data += sizeof(long); - } - ret = 0; - goto out; - }; - - case PTRACE_GETFPREGS: { /* Get the child FPU state. */ - if (!access_ok(VERIFY_WRITE, (unsigned *)data, - sizeof(struct user_i387_struct))) - { - ret = -EIO; - goto out; - } - ret = 0; - if ( !child->used_math ) { - /* Simulate an empty FPU. */ - child->thread.i387.hard.cwd = 0xffff037f; - child->thread.i387.hard.swd = 0xffff0000; - child->thread.i387.hard.twd = 0xffffffff; - } - __copy_to_user((void *)data, &child->thread.i387.hard, - sizeof(struct user_i387_struct)); - goto out; - }; - - case PTRACE_SETFPREGS: { /* Set the child FPU state. */ - if (!access_ok(VERIFY_READ, (unsigned *)data, - sizeof(struct user_i387_struct))) - { - ret = -EIO; - goto out; - } - child->used_math = 1; - __copy_from_user(&child->thread.i387.hard, (void *)data, - sizeof(struct user_i387_struct)); - ret = 0; - goto out; - }; -#endif - default: - ret = -EIO; - goto out; + ubc_set_tracing(child->mm->context & MMU_CONTEXT_ASID_MASK, + nextpc1, nextpc2); + + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; + break; + } + + case PTRACE_DETACH: { /* detach a process that was attached. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->flags &= ~(PF_PTRACED|PF_TRACESYS); + child->exit_code = data; + write_lock_irqsave(&tasklist_lock, flags); + REMOVE_LINKS(child); + child->p_pptr = child->p_opptr; + SET_LINKS(child); + write_unlock_irqrestore(&tasklist_lock, flags); + wake_up_process(child); + ret = 0; + break; + } + + default: + ret = -EIO; + break; } out: unlock_kernel(); @@ -457,20 +378,22 @@ out: asmlinkage void syscall_trace(void) { - if ((current->flags & (PF_PTRACED|PF_TRACESYS)) - != (PF_PTRACED|PF_TRACESYS)) + struct task_struct *tsk = current; + + if ((tsk->flags & (PF_PTRACED|PF_TRACESYS)) + != (PF_PTRACED|PF_TRACESYS)) return; - current->exit_code = SIGTRAP; - current->state = TASK_STOPPED; - notify_parent(current, SIGCHLD); + tsk->exit_code = SIGTRAP; + tsk->state = TASK_STOPPED; + notify_parent(tsk, SIGCHLD); schedule(); /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; + if (tsk->exit_code) { + send_sig(tsk->exit_code, tsk, 1); + tsk->exit_code = 0; } } diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 0c24acf73..4b11100ae 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.16 2000/01/29 11:31:31 gniibe Exp gniibe $ +/* $Id: signal.c,v 1.21 2000/03/11 14:06:21 gniibe Exp $ * * linux/arch/sh/kernel/signal.c * @@ -6,7 +6,7 @@ * * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * - * SuperH version: Copyright (C) 1999 Niibe Yutaka + * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * */ @@ -125,7 +125,7 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss, unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_sigaltstack(uss, uoss, regs.sp); + return do_sigaltstack(uss, uoss, regs.regs[15]); } @@ -136,7 +136,6 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct sigframe { struct sigcontext sc; - /* FPU data should come here: SH-3 has no FPU */ unsigned long extramask[_NSIG_WORDS-1]; char retcode[4]; }; @@ -147,10 +146,38 @@ struct rt_sigframe void *puc; struct siginfo info; struct ucontext uc; - /* FPU should come here: SH-3 has no FPU */ char retcode[4]; }; +#if defined(__SH4__) +static inline int restore_sigcontext_fpu(struct sigcontext *sc) +{ + current->used_math = 1; + return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0], + sizeof(long)*(NUM_FPU_REGS*2+2)); +} + +static inline int save_sigcontext_fpu(struct sigcontext *sc) +{ + struct task_struct *tsk = current; + + if (!tsk->used_math) { + sc->owend_fp = 0; + return 0; + } + + sc->owend_fp = 1; + + /* This will cause a "finit" to be triggered by the next + attempted FPU operation by the 'current' process. + */ + tsk->used_math = 0; + + unlazy_fpu(tsk); + return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, + sizeof(long)*(NUM_FPU_REGS*2+2)); +} +#endif static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *r0_p) @@ -165,15 +192,28 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *r0_p) COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); COPY(regs[12]); COPY(regs[13]); - COPY(regs[14]); COPY(sp); + COPY(regs[14]); COPY(regs[15]); COPY(gbr); COPY(mach); COPY(macl); COPY(pr); COPY(sr); COPY(pc); #undef COPY +#if defined(__SH4__) + { + int owned_fp; + struct task_struct *tsk = current; + + regs->sr |= SR_FD; /* Release FPU */ + clear_fpu(tsk); + current->used_math = 0; + __get_user (owned_fp, &context->sc_ownedfp); + if (owned_fp) + err |= restore_sigcontext_fpu(sc); + } +#endif + regs->syscall_nr = -1; /* disable syscall checks */ err |= __get_user(*r0_p, &sc->sc_regs[0]); - return err; } @@ -181,7 +221,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - struct sigframe *frame = (struct sigframe *)regs.sp; + struct sigframe *frame = (struct sigframe *)regs.regs[15]; sigset_t set; int r0; @@ -214,7 +254,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - struct rt_sigframe *frame = (struct rt_sigframe *)regs.sp; + struct rt_sigframe *frame = (struct rt_sigframe *)regs.regs[15]; sigset_t set; stack_t st; int r0; @@ -238,7 +278,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs.sp); + do_sigaltstack(&st, NULL, regs.regs[15]); return r0; @@ -265,12 +305,16 @@ setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); COPY(regs[12]); COPY(regs[13]); - COPY(regs[14]); COPY(sp); + COPY(regs[14]); COPY(regs[15]); COPY(gbr); COPY(mach); COPY(macl); COPY(pr); COPY(sr); COPY(pc); #undef COPY +#if defined(__SH4__) + err |= save_sigcontext_fpu(sc); +#endif + /* non-iBCS2 extensions.. */ err |= __put_user(mask, &sc->oldmask); @@ -296,7 +340,7 @@ static void setup_frame(int sig, struct k_sigaction *ka, int err = 0; int signal; - frame = get_sigframe(ka, regs->sp, sizeof(*frame)); + frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; @@ -334,7 +378,7 @@ static void setup_frame(int sig, struct k_sigaction *ka, goto give_sigsegv; /* Set up registers for signal handler */ - regs->sp = (unsigned long) frame; + regs->regs[15] = (unsigned long) frame; regs->regs[4] = signal; /* Arg for signal handler */ regs->pc = (unsigned long) ka->sa.sa_handler; @@ -361,7 +405,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, int err = 0; int signal; - frame = get_sigframe(ka, regs->sp, sizeof(*frame)); + frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; @@ -381,7 +425,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(0, &frame->uc.uc_link); err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags); + err |= __put_user(sas_ss_flags(regs->regs[15]), + &frame->uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); @@ -407,7 +452,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, goto give_sigsegv; /* Set up registers for signal handler */ - regs->sp = (unsigned long) frame; + regs->regs[15] = (unsigned long) frame; regs->regs[4] = signal; /* Arg for signal handler */ regs->pc = (unsigned long) ka->sa.sa_handler; diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 5f7d68755..7af24f1c3 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a L_OBJS = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index f5c5200be..33bdf2114 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -1,4 +1,4 @@ -/* $Id: cache.c,v 1.9 2000/02/14 12:45:26 gniibe Exp $ +/* $Id: cache.c,v 1.10 2000/03/07 11:58:34 gniibe Exp $ * * linux/arch/sh/mm/cache.c * @@ -67,36 +67,15 @@ static struct _cache_system_info cache_system_info; #define CACHE_IC_NUM_WAYS 1 #endif -#define jump_to_p2(__dummy) \ - asm volatile("mova 1f,%0\n\t" \ - "add %1,%0\n\t" \ - "jmp @r0 ! Jump to P2 area\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1:" \ - : "=&z" (__dummy) \ - : "r" (0x20000000)) - -#define back_to_p1(__dummy) \ - asm volatile("nop;nop;nop;nop;nop;nop\n\t" \ - "mova 9f,%0\n\t" \ - "sub %1,%0\n\t" \ - "jmp @r0 ! Back to P1 area\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "9:" \ - : "=&z" (__dummy) \ - : "r" (0x20000000), "0" (__dummy)) - /* Write back caches to memory (if needed) and invalidates the caches */ void cache_flush_area(unsigned long start, unsigned long end) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, v, p; start &= ~(L1_CACHE_BYTES-1); save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { p = __pa(v); @@ -110,7 +89,7 @@ void cache_flush_area(unsigned long start, unsigned long end) : "m" (__m(v))); #endif } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } @@ -124,12 +103,12 @@ void cache_flush_area(unsigned long start, unsigned long end) the cache line. */ void cache_purge_area(unsigned long start, unsigned long end) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, v, p, j; start &= ~(L1_CACHE_BYTES-1); save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { p = __pa(v); @@ -150,19 +129,19 @@ void cache_purge_area(unsigned long start, unsigned long end) : "m" (__m(v))); #endif } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } /* write back the dirty cache, but not invalidate the cache */ void cache_wback_area(unsigned long start, unsigned long end) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long v; start &= ~(L1_CACHE_BYTES-1); save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { #if CACHE_IC_ADDRESS_ARRAY == CACHE_OC_ADDRESS_ARRAY @@ -187,7 +166,7 @@ void cache_wback_area(unsigned long start, unsigned long end) : "m" (__m(v))); #endif } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } @@ -199,11 +178,11 @@ void cache_wback_area(unsigned long start, unsigned long end) */ static void cache_wback_all(void) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, i, j; save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { for (j=0; j<CACHE_OC_NUM_WAYS; j++) { @@ -217,7 +196,7 @@ static void cache_wback_all(void) } } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } @@ -225,9 +204,9 @@ static void detect_cpu_and_cache_system(void) { #if defined(__sh3__) - unsigned long __dummy, addr0, addr1, data0, data1, data2, data3; + unsigned long addr0, addr1, data0, data1, data2, data3; - jump_to_p2(__dummy); + jump_to_P2(); /* Check if the entry shadows or not. * When shadowed, it's 128-entry system. * Otherwise, it's 256-entry system. @@ -245,7 +224,7 @@ detect_cpu_and_cache_system(void) /* Invaliate them, in case the cache has been enabled already. */ ctrl_outl(data0&~0x00000001,addr0); ctrl_outl(data2&~0x00000001,addr1); - back_to_p1(__dummy); + back_to_P1(); if (data0 == data1 && data2 == data3) { /* Shadow */ cache_system_info.way_shift = 11; @@ -265,7 +244,7 @@ detect_cpu_and_cache_system(void) void __init cache_init(void) { - unsigned long __dummy, ccr; + unsigned long ccr; detect_cpu_and_cache_system(); @@ -277,19 +256,19 @@ void __init cache_init(void) we only need to flush the half of the caches. */ cache_wback_all(); - jump_to_p2(__dummy); + jump_to_P2(); ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_p1(__dummy); + back_to_P1(); } #if defined(__SH4__) void flush_icache_page(struct vm_area_struct *vma, struct page *pg) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, v; save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); v = page_address(pg); @@ -303,18 +282,18 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *pg) data = (v&0xfffffc00); /* Valid=0 */ ctrl_outl(data,addr); - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } void flush_icache_range(unsigned long start, unsigned long end) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, v; start &= ~(L1_CACHE_BYTES-1); save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { /* Write back O Cache */ @@ -327,22 +306,22 @@ void flush_icache_range(unsigned long start, unsigned long end) data = (v&0xfffffc00); /* Valid=0 */ ctrl_outl(data,addr); } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } void flush_cache_all(void) { - unsigned long flags,__dummy; + unsigned long flags; /* Write back Operand Cache */ cache_wback_all (); /* Then, invalidate Instruction Cache and Operand Cache */ save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } @@ -356,12 +335,12 @@ void flush_cache_mm(struct mm_struct *mm) void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - unsigned long flags, __dummy; + unsigned long flags; unsigned long addr, data, v; start &= ~(L1_CACHE_BYTES-1); save_and_cli(flags); - jump_to_p2(__dummy); + jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { addr = CACHE_IC_ADDRESS_ARRAY | @@ -372,7 +351,7 @@ void flush_cache_range(struct mm_struct *mm, unsigned long start, (v&CACHE_OC_ENTRY_MASK) | 0x8 /* A-bit */; ctrl_outl(data,addr); } - back_to_p1(__dummy); + back_to_P1(); restore_flags(flags); } diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 3b8e86e36..bf448bf8b 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.12 2000/03/01 11:15:27 gniibe Exp $ +/* $Id: fault.c,v 1.13 2000/03/07 12:05:24 gniibe Exp $ * * linux/arch/sh/mm/fault.c * Copyright (C) 1999 Niibe Yutaka @@ -283,9 +283,6 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page) { unsigned long addr, data, asid; unsigned long saved_asid = MMU_NO_ASID; -#if defined(__SH4__) - int i; -#endif if (mm->context == NO_CONTEXT) return; @@ -305,20 +302,26 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page) data = (page & 0xfffe0000) | asid; /* VALID bit is off */ ctrl_outl(data, addr); #elif defined(__SH4__) + jump_to_P2(); addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT; data = page | asid; /* VALID bit is off */ ctrl_outl(data, addr); - - for (i=0; i<4; i++) { - addr = MMU_ITLB_ADDRESS_ARRAY | (i<<8); - data = ctrl_inl(addr); - data &= ~0x300; - if (data == (page | asid)) { - ctrl_outl(data, addr); - break; +#if 0 /* Not need when using ASSOC. ??? */ + { + int i; + for (i=0; i<4; i++) { + addr = MMU_ITLB_ADDRESS_ARRAY | (i<<8); + data = ctrl_inl(addr); + data &= ~0x300; + if (data == (page | asid)) { + ctrl_outl(data, addr); + break; + } } } #endif + back_to_P1(); +#endif if (saved_asid != MMU_NO_ASID) set_asid(saved_asid); } diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 776389cac..931564cac 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -224,7 +224,7 @@ void __init paging_init(void) zones_size[ZONE_DMA] = max_dma - start_pfn; zones_size[ZONE_NORMAL] = low - max_dma; } - free_area_init_node(0, 0, zones_size, __MEMORY_START); + free_area_init_node(0, 0, zones_size, __MEMORY_START, 0); } } |