You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
(12) |
May
(82) |
Jun
(72) |
Jul
(39) |
Aug
(104) |
Sep
(61) |
Oct
(55) |
Nov
(101) |
Dec
(48) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(52) |
Feb
(67) |
Mar
(18) |
Apr
(16) |
May
(33) |
Jun
(12) |
Jul
(102) |
Aug
(168) |
Sep
(65) |
Oct
(60) |
Nov
(43) |
Dec
(121) |
2002 |
Jan
(69) |
Feb
(32) |
Mar
(90) |
Apr
(59) |
May
(45) |
Jun
(43) |
Jul
(33) |
Aug
(21) |
Sep
(11) |
Oct
(20) |
Nov
(26) |
Dec
(3) |
2003 |
Jan
(12) |
Feb
(18) |
Mar
(11) |
Apr
(11) |
May
(41) |
Jun
(76) |
Jul
(77) |
Aug
(15) |
Sep
(38) |
Oct
(56) |
Nov
(19) |
Dec
(39) |
2004 |
Jan
(17) |
Feb
(52) |
Mar
(36) |
Apr
(34) |
May
(48) |
Jun
(85) |
Jul
(38) |
Aug
(42) |
Sep
(41) |
Oct
(77) |
Nov
(27) |
Dec
(19) |
2005 |
Jan
(32) |
Feb
(35) |
Mar
(29) |
Apr
(8) |
May
(7) |
Jun
(31) |
Jul
(46) |
Aug
(93) |
Sep
(65) |
Oct
(85) |
Nov
(219) |
Dec
(47) |
2006 |
Jan
(170) |
Feb
(103) |
Mar
(49) |
Apr
(43) |
May
(45) |
Jun
(29) |
Jul
(77) |
Aug
(82) |
Sep
(43) |
Oct
(45) |
Nov
(26) |
Dec
(85) |
2007 |
Jan
(42) |
Feb
(48) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(53) |
Jul
(175) |
Aug
(212) |
Sep
(91) |
Oct
(103) |
Nov
(110) |
Dec
(5) |
2008 |
Jan
(20) |
Feb
(11) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(5) |
Sep
(3) |
Oct
(12) |
Nov
|
Dec
|
From: NIIBE Y. <gn...@m1...> - 2002-04-05 01:01:43
|
Robert Love wrote: > So what will it take to get kernel preemption support added? :) > > preempt-kernel has been in 2.5 since 2.5.4-pre. The work required to > add it to the SH architecture is fairly minimal, with most of the work > being in entry.S. If you look at MontaVista's (Jeremy Siegel's) SH > preempt support for 2.4, the work for 2.5 is about the same. The main > difference in 2.5 is the use of the thread_info structure for > preempt_count and that the interrupt return path no longer calls > preempt_schedule, but schedule itself. > > I'd be happy to help ... Thanks to point it out. I was thinking about it. Yes, I think that it's ready to merge the preemption work. If you or Jeremy go ahead to do so, it's welcome. Well, I have a issue. __copy_user_page or __clear_user_page is the most time consuming routine in the kernel. For SH-4, we could use FPU registers to transfer 8-byte at a instruction to improve speed (in theory, I haven't tested). This would improve performance of usual case, but I think that we need to inhibit preemption to protect FPU usage in the kernel. Here we would have large latency. I'm afraid of this, so I haven't moved to page copying/clearing with FPU registers... -- |
From: Robert L. <rm...@te...> - 2002-04-04 18:34:21
|
On Thu, 2002-04-04 at 04:03, NIIBE Yutaka wrote: > Now is the time to sync up to mainline. > Paul, please note that the change of shwdt.c is from the mainline. So what will it take to get kernel preemption support added? :) preempt-kernel has been in 2.5 since 2.5.4-pre. The work required to add it to the SH architecture is fairly minimal, with most of the work being in entry.S. If you look at MontaVista's (Jeremy Siegel's) SH preempt support for 2.4, the work for 2.5 is about the same. The main difference in 2.5 is the use of the thread_info structure for preempt_count and that the interrupt return path no longer calls preempt_schedule, but schedule itself. I'd be happy to help ... Robert Love |
From: akira <aki...@ho...> - 2002-04-04 16:36:53
|
=20 Hello to all, now my kernel work, but I do not succeed to mount a NFS filesystem. On the host computer work: portmapper, mountd, nfs. I have shaped also = the file export. What means: VFS: Cannot open root device "nfs" or 00:ff Please append a correct "root=3D" boot option Kernel panic: VFS: Unable to mount root fs on 00:ff What I can make in order to make he to work correctly? Which are the options that I must choose in menuconfig in order making = to work the kernel with a NFS filesystem? Thanks! SH IPL+g version 0.11, Copyright (C) 2001 Free Software Foundation, Inc. This software comes with ABSOLUTELY NO WARRANTY; for details type `w'. This is free software, and you are welcome to redistribute it under certain conditions; type `l' for details. > h SH IPL+g version 0.11, Copyright (C) 2001 Free Software Foundation, Inc. ? --- Show this message (HELP) b --- Boot the system g --- Invoke GDB stub l --- Show about license w --- Show about (no)warranty e --- Ether Boot > e Booting from network! Searching for server (BOOTP/DHCP)... <sleep> IP Address: 1.255.12.12 Server: 1.255.12.237, Gateway 1.255.8.1 Kernel to load: "/tftpboot/boot/zImage" HOSTNAME: terra ROOT PATH: /home/akira/project/finale/tmp/rootfsdir Loading Kernel: /tftpboot/boot/zImage = .........................................................................= .........................................................................= .........................................................................= .........................................................................= ........SUM: 25f9c0f done Uncompressing Linux... Ok, booting the kernel. Linux version 2.4.18-sh (root@linux) (gcc version 3.0.3) #11 Fri Mar 29 = 16:22:37 CET 2002 On node 0 totalpages: 4096 zone(0): 4096 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: mem=3D16M sh_mv=3DSolutionEngine = console=3DttySC1,115200 root=3D/dev/nfs rw = nfsroot=3D1.255.12.237:/home/akira/project/finale/tmp/rootfsdir = ip=3D1.255.12.12:1.255.12.237:1.255.8.1:255.255.255.0:terra:eth0:off Setting GDB trap vector to 0x80000100 CPU clock: 133.34MHz Bus clock: 66.67MHz Module clock: 33.33MHz Interval =3D 83338 Linux version 2.4.18-sh (root@linux) (gcc version 3.0.3) #11 Fri Mar 29 = 16:22:37 CET 2002 Linux version 2.4.18-sh (root@linux) (gcc version 3.0.3) #11 Fri Mar 29 = 16:22:37 CET 2002 On node 0 totalpages: 4096 On node 0 totalpages: 4096 zone(0): 4096 pages. zone(0): 4096 pages. zone(1): 0 pages. zone(1): 0 pages. zone(2): 0 pages. zone(2): 0 pages. Kernel command line: mem=3D16M sh_mv=3DSolutionEngine = console=3DttySC1,115200 root=3D/dev/nfs rw = nfsroot=3D1.255.12.237:/home/akira/project/finale/tmp/rootfsdir = ip=3D1.255.12.12:1.255.12.237:1.255.8.1:255.255.255.0:terra:eth0:off Kernel command line: mem=3D16M sh_mv=3DSolutionEngine = console=3DttySC1,115200 root=3D/dev/nfs rw = nfsroot=3D1.255.12.237:/home/akira/project/finale/tmp/rootfsdir = ip=3D1.255.12.12:1.255.12.237:1.255.8.1:255.255.255.0:terra:eth0:off Setting GDB trap vector to 0x80000100 Setting GDB trap vector to 0x80000100 CPU clock: 133.34MHz CPU clock: 133.34MHz Bus clock: 66.67MHz Bus clock: 66.67MHz Module clock: 33.33MHz Module clock: 33.33MHz Interval =3D 83338 Interval =3D 83338 Calibrating delay loop... 66.56 BogoMIPS Memory: 15452k/16384k available (495k kernel code, 932k reserved, 18k = data, 24k init) Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes) Inode-cache hash table entries: 1024 (order: 1, 8192 bytes) Mount-cache hash table entries: 512 (order: 0, 4096 bytes) Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes) Page-cache hash table entries: 4096 (order: 2, 16384 bytes) CPU: SH7709A/SH7729 POSIX conformance testing by UNIFIX Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket Starting kswapd SuperH SCI(F) driver initialized ttySC0 at 0xfffffe80 is a SCI ttySC1 at 0xa4000150 is a SCIF ttySC2 at 0xa4000140 is a SCIF block: 64 slots per queue, batch=3D16 VFS: Cannot open root device "nfs" or 00:ff Please append a correct "root=3D" boot option Kernel panic: VFS: Unable to mount root fs on 00:ff |
From: Fabio G. <fg...@ti...> - 2002-04-04 11:01:01
|
I found what was the problem of the interrupt (PINT initialization); Now, where can I find the guidelines to implement the support for video in framebuffer and keyboard? On Wednesday 03 April 2002 20:18, Stuart Menefy wrote: > Fabio > > If you look at the bit of code in assembler, it reads the value from > the INTEVT register, shifts right by 5 and subtracts 16. So an interrupt > code of 0xd corrisponds to INTEVT code of 0x3a0. Have a look at the > interrupt code table in the appropriate manual, and you'll see which > interrupt this corrisponds to. I don't have a 7709 manual to hand, > but IIRC this is an external interrupt on all SuperH parts. > > So something on your board is raising an interrupt, and this error > message is saying that there is no interrupt handler installed to > handle it. > > This could just be a mis-configuration issue. The interrupt controllers > on some of the SH3's have quite a few modes and config registers. When > your board was designed, they probably intended the interrupt controller > to be set up in a particular way, make sure you're doing this. > > Alternativly something on your board really is raising an interrupt. > > Hopefully your board has some external logic to control enabling and > disabling of interrupts from peripherials, so maybe this needs to be > set up before you enable interrupts at the CPU level. > > Or maybe the device which is raising the interrupt at boot time needs > to be initialised first. > > Either would be pretty grotty, most devices power up with interrupts > disabled and/or inactive until you do something to provoke them, but > it wouldn't be the first time somebody had designed hardware that didn't > work that way. > > If all else fails, you could look at using the irq_imask routines to > disable the interrupt using the IMASK in the status register, but > that should be a last resort, as it results in all interrupts of lower > priority being disabled, so could disbale something you need. > > Hope this helps > > Stuart > > > > On Wed, 3 Apr 2002 16:12:28 +0200 > > fg...@ti... wrote: > > Sorry, > > but I don't understand what means: > > "unexpected IRQ trap at vector 0d" > > > > I suppose it is an interrupt always entering but I don't understand what > > is its source. > > > > Thanks. > > > > Fabio > > > > On Tuesday 02 April 2002 14:27, Stuart Menefy wrote: > > > Hi Fabio > > > > > > You might like to have a look at the 'board porting guide' a colleague > > > here wrote. Have a look at: > > > http://www.linuxsh.st.com/getting_started/board_porting.php3 > > > > > > As far as I know, you'll be the first person to try it in anger, so any > > > comments welcome! > > > > > > You're right, it sounds like you have a pending interrupt. So the first > > > thing I'd do is stick a printk at the start of do_IRQ(), and print the > > > irq number (just after the little bit of asm code which retreives it). > > > > > > Stuart > > > > > > > > > On Fri, 29 Mar 2002 10:55:32 +0100 > > > > > > fg...@ti... wrote: > > > > Hi, Stuart, > > > > I' porting linux SH on my sh3 7709a based board. > > > > I'm able to compile and run for my board sh-boot got from CVS > > > > repository, I'm able to compile the kernel 2.4.18 and I can boot it > > > > using gdb. > > > > > > > > Making a debug using printk("...."); while(1); to understant I see > > > > that kernel stops execution at init/main.c -> start_kernel -> sti(); > > > > > > > > I compiled my kernel as my board were a SolutionEngine, but my board > > > > isn't a SolutionEngine. > > > > > > > > Having read the Documentation/sh/ document from the CVS kernel and > > > > seeing you are the father of sh_mv model, I write to you for asking: > > > > 1) Is it possible when I enable the interrupt mask with sti() an > > > > interrupt pending occurs which I have no handler for? > > > > > > > > 2) There is an optiminezed way to trace this kind of troubles? > > > > > > > > > > > > Thanks a lot. > > > > > > > > Fabio |
From: NIIBE Y. <gn...@m1...> - 2002-04-04 10:15:52
|
I'll send following patch set to Linus to sync. I'll send only SuperH specific change, leaving drivers changes in our repository. -------------------------- Here's the SuperH update. All changes are SuperH specific. (i.e., under arch/sh/ or include/asm-sh/) Follow up: Introduce thread_info. Implemented (mostly copied from i386 implementation.) Scheduler: sched_find_first_bit, switch_to Macros: SI_DETHREAD, PROT_SEM, VM_DATA_DEFAULT_FLAGS, and PCI_DMA_BUS_IS_PHYS Page handling: pmd_*, pte_* functions/macros change Cache handling function: flush_icache_user_range New system calles: gettid, .., futex Bug fixes: Paul Mundt: arch/sh/kernel/io_7751se.c: Typo fix. Niibe Yutaka: Init task fpu initialization. Signal return. Improvement: Paul Mundt, Niibe Yutaka: arch/sh/mm/cache-sh4.c flush_cache_range implemented (was: flush_cache_all). Paul Mundt: arch/sh/kernel/traps.c show_trace_task implemented. Others: Niibe Yutaka: FPU cleanup Implement kernel profile function (sh_do_profile). diff -ru3pN linux-2.5.8-pre1/arch/sh/Config.help linux-2.5.8-pre1.superh/arch/sh/Config.help --- linux-2.5.8-pre1/arch/sh/Config.help Fri Mar 22 14:11:24 2002 +++ linux-2.5.8-pre1.superh/arch/sh/Config.help Fri Mar 22 13:49:37 2002 @@ -754,6 +754,13 @@ CONFIG_SH_DREAMCAST <http://www.m17n.org/linux-sh/dreamcast/>. There is a Dreamcast project is at <http://linuxdc.sourceforge.net/>. +CONFIG_SH_SH2000 + SH-2000 is a single-board computer based around SH7709A chip + intended for embedded applications. + It has an Ethernet interface (CS8900A), direct connected + Compact Flash socket, three serial ports and PC-104 bus. + More information at <http://sh2000.sh-linux.org>. + CONFIG_SH_UNKNOWN "Bare CPU" aka "unknown" means an SH-based system which is not one of the specific ones mentioned above, which means you need to enter @@ -790,6 +797,12 @@ CONFIG_CPU_SUBTYPE_SH7709 CONFIG_CPU_SUBTYPE_SH7750 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. + +CONFIG_CPU_SUBTYPE_SH7751 + Select SH7750 if you have a 166 Mhz SH-4 HD6417751 CPU. + +CONFIG_CPU_SUBTYPE_ST40STB1 + Select ST40STB1 if you have a ST40STB1 CPU. CONFIG_MEMORY_START Computers built with Hitachi SuperH processors always diff -ru3pN linux-2.5.8-pre1/arch/sh/config.in linux-2.5.8-pre1.superh/arch/sh/config.in --- linux-2.5.8-pre1/arch/sh/config.in Fri Mar 22 14:11:25 2002 +++ linux-2.5.8-pre1.superh/arch/sh/config.in Fri Mar 22 13:49:37 2002 @@ -258,7 +258,7 @@ fi endmenu # -# input before char - char/joystick depends on it. As does USB. +# input - input/joystick depends on it. As does USB. # source drivers/input/Config.in @@ -307,7 +307,7 @@ if [ "$CONFIG_SH_DREAMCAST" = "y" -a "$C endmenu fi -source drivers/char/joystick/Config.in +source drivers/input/joystick/Config.in if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/entry.S linux-2.5.8-pre1.superh/arch/sh/kernel/entry.S --- linux-2.5.8-pre1/arch/sh/kernel/entry.S Mon Feb 11 10:50:15 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/entry.S Fri Mar 29 09:02:04 2002 @@ -1,8 +1,8 @@ -/* $Id: entry.S,v 1.71 2001/07/27 11:47:50 gniibe Exp $ +/* $Id: entry.S,v 1.72 2002/03/29 00:02:04 gniibe Exp $ * * linux/arch/sh/entry.S * - * Copyright (C) 1999, 2000 Niibe Yutaka + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka * * 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 @@ -13,13 +13,11 @@ #include <linux/sys.h> #include <linux/linkage.h> #include <linux/config.h> +#include <asm/thread_info.h> - -/* - * Define this to turn on compatibility with the previous - * system call ABI. This feature is not properly maintained. - */ -#undef COMPAT_OLD_SYSCALL_ABI +#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) +#define sys_nfsservctl sys_ni_syscall +#endif ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -57,16 +55,6 @@ * */ -/* - * These are offsets into the task-struct. - */ -flags = 4 -#error sigpending = 8 -#error need_resched = 20 -#error tsk_ptrace = 24 - -#error PT_TRACESYS = 0x00000002 - ENOSYS = 38 EINVAL = 22 @@ -87,17 +75,17 @@ MMU_TEA = 0xff00000c ! TLB Exception Ad #endif /* Offsets to the stack */ -OFF_R0 = 0 /* Return value. New ABI also arg4 */ -OFF_R1 = 4 /* New ABI: arg5 */ -OFF_R2 = 8 /* New ABI: arg6 */ -OFF_R3 = 12 /* New ABI: syscall_nr */ -OFF_R4 = 16 /* New ABI: arg0 */ -OFF_R5 = 20 /* New ABI: arg1 */ -OFF_R6 = 24 /* New ABI: arg2 */ -OFF_R7 = 28 /* New ABI: arg3 */ -OFF_SP = (15*4) -OFF_SR = (16*4+8) -SYSCALL_NR = (16*4+6*4) +OFF_R0 = 0 /* Return value. New ABI also arg4 */ +OFF_R1 = 4 /* New ABI: arg5 */ +OFF_R2 = 8 /* New ABI: arg6 */ +OFF_R3 = 12 /* New ABI: syscall_nr */ +OFF_R4 = 16 /* New ABI: arg0 */ +OFF_R5 = 20 /* New ABI: arg1 */ +OFF_R6 = 24 /* New ABI: arg2 */ +OFF_R7 = 28 /* New ABI: arg3 */ +OFF_SP = (15*4) +OFF_SR = (16*4+8) +OFF_TRA = (16*4+6*4) #define k0 r0 @@ -106,11 +94,10 @@ SYSCALL_NR = (16*4+6*4) #define k3 r3 #define k4 r4 -#define current r7 /* r7_bank1 */ +#define k_ex_code r2_bank /* r2_bank1 */ #define g_imask r6 /* r6_bank1 */ -#define k_current r7_bank /* r7_bank1 */ #define k_g_imask r6_bank /* r6_bank1 */ -#define k_ex_code r2_bank /* r2_bank1 */ +#define current r7 /* r7_bank1 */ /* * Kernel mode register usage: @@ -121,7 +108,7 @@ SYSCALL_NR = (16*4+6*4) * k4 scratch * k5 reserved * k6 Global Interrupt Mask (0--15 << 4) - * k7 CURRENT (pointer to current task) + * k7 CURRENT_THREAD_INFO (pointer to current thread info) */ ! @@ -142,7 +129,7 @@ SYSCALL_NR = (16*4+6*4) mov.l __INV_IMASK, r11; \ stc sr, r10; \ and r11, r10; \ - stc k_g_imask, r11; \ + stc k_g_imask, r11; \ or r11, r10; \ ldc r10, sr @@ -208,6 +195,7 @@ address_error_store: bra call_dae mov #1,r5 ! writeaccess = 1 + .align 2 call_dae: mov.l 1f, r0 mov.l @r0, r6 ! address @@ -269,56 +257,125 @@ debug_trap: shll r0 ! kernel space? bt/s debug_kernel #endif - mov.l @r15, r0 + mov.l @r15, r0 ! Restore R0 value mov.l 1f, r8 jmp @r8 nop .align 2 -1: .long SYMBOL_NAME(break_point_trap_software) - - .align 2 error: ! STI() - mov.l 1f, r0 + mov.l 2f, r0 jmp @r0 nop + +! + .align 2 +1: .long SYMBOL_NAME(break_point_trap_software) +2: .long SYMBOL_NAME(do_exception_error) + .align 2 -1: .long SYMBOL_NAME(do_exception_error) +ret_from_irq: +ret_from_exception: + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + shll r0 + shll r0 ! kernel space? + bt/s restore_all ! Yes, it's from kernel, go back soon + GET_THREAD_INFO(r8) +ENTRY(resume_userspace) + ! r8: current_thread_info + /* CLI */ + stc sr, r0 + or #0xf0, r0 + ldc r0, sr + ! + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt/s restore_all + tst #_TIF_NEED_RESCHED, r0 -! -! -! -ENTRY(ret_from_fork) - mov.l @r15+,r0 - ! Call schedule_tail + .align 2 +work_pending: + ! r0: current_thread_info->flags + ! r8: current_thread_info + ! t: result of "tst #_TIF_NEED_RESCHED, r0" + bf/s work_resched + tst #_TIF_SIGPENDING, r0 +work_notifysig: + bt/s restore_all + mov r15, r4 + mov #0, r5 + mov.l 2f, r1 + mova restore_all, r0 + jmp @r1 + lds r0, pr +work_resched: mov.l 1f, r1 - jsr @r1 - mov r0, r4 - ! If we're being traced, return via syscall_ret_trace, otherwise - ! return directly to ret_from_syscall - stc k_current, r0 -#error mov.l @(tsk_ptrace,r0), r0 ! Is current PTRACE_SYSCALL'd? -#error mov #PT_TRACESYS, r1 - tst r1, r0 - bt ret_from_syscall - bra syscall_ret_trace - nop + jsr @r1 ! schedule + nop + /* CLI */ + stc sr, r0 + or #0xf0, r0 + ldc r0, sr + ! + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt restore_all + bra work_pending + tst #_TIF_NEED_RESCHED, r0 .align 2 -1: .long SYMBOL_NAME(schedule_tail) +1: .long SYMBOL_NAME(schedule) +2: .long SYMBOL_NAME(do_signal) + + .align 2 +syscall_exit_work: + ! r0: current_thread_info->flags + ! r8: current_thread_info + tst #_TIF_SYSCALL_TRACE, r0 + bt/s work_pending + tst #_TIF_NEED_RESCHED, r0 + STI() + ! XXX setup arguments... + mov.l 4f, r0 ! do_syscall_trace + jsr @r0 + nop + bra resume_userspace + nop + + .align 2 +syscall_trace_entry: + ! Yes it is traced. + ! XXX setup arguments... + mov.l 4f, r11 ! Call do_syscall_trace which notifies + jsr @r11 ! superior (will chomp R[0-7]) + nop + ! Reload R0-R4 from kernel stack, where the + ! parent may have modified them using + ! ptrace(POKEUSR). (Note that R0-R2 are + ! used by the system call handler directly + ! from the kernel stack anyway, so don't need + ! to be reloaded here.) This allows the parent + ! to rewrite system calls and args on the fly. + mov.l @(OFF_R4,r15), r4 ! arg0 + mov.l @(OFF_R5,r15), r5 + mov.l @(OFF_R6,r15), r6 + mov.l @(OFF_R7,r15), r7 ! arg3 + mov.l @(OFF_R3,r15), r3 ! syscall_nr + ! Arrange for do_syscall_trace to be called + ! again as the system call returns. + mov.l 2f, r10 ! Number of syscalls + cmp/hs r10, r3 + bf syscall_call + mov #-ENOSYS, r0 + bra syscall_exit + mov.l r0, @(OFF_R0,r15) ! Return value /* - * Old syscall interface: - * - * Syscall #: R0 - * Arguments #0 to #3: R4--R7 - * more arguments: On the stack - * TRA: (number of arguments on the stack) x 4 - * - * New syscall interface: + * Syscall interface: * * Syscall #: R3 * Arguments #0 to #3: R4--R7 @@ -340,231 +397,58 @@ ENTRY(ret_from_fork) * argument. */ + .align 2 system_call: - mov.l __TRA, r9 - mov.l @r9, r8 + mov.l 1f, r9 + mov.l @r9, r8 ! Read from TRA (Trap Address) Register ! ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x20, r9 - extu.b r9, r9 - shll2 r9 - cmp/hs r9, r8 - bt debug_trap - ! - mov #SYSCALL_NR, r14 - add r15, r14 - ! -#ifdef COMPAT_OLD_SYSCALL_ABI - mov #0x40, r9 - cmp/hs r9, r8 - bf/s old_abi_system_call - nop -#endif - ! New Syscall ABI - add #-0x40, r8 - shlr2 r8 - shll8 r8 - shll8 r8 ! r8 = num_args<<16 - mov r3, r10 - or r8, r10 ! Encode syscall # and # of arguments - mov.l r10, @r14 ! set syscall_nr - STI() + mov #0x7f, r9 + cmp/hi r9, r8 + bt/s debug_trap + mov #OFF_TRA, r9 + add r15, r9 ! - stc k_current, r11 -#error mov.l @(tsk_ptrace,r11), r10 ! Is current PTRACE_SYSCALL'd? -#error mov #PT_TRACESYS, r11 - tst r11, r10 - bt 5f - ! Yes it is traced. - mov.l __syscall_trace, r11 ! Call syscall_trace() which notifies - jsr @r11 ! superior (will chomp R[0-7]) - nop - ! Reload R0-R4 from kernel stack, where the - ! parent may have modified them using - ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. - mov.l @(OFF_R4,r15), r4 ! arg0 - mov.l @(OFF_R5,r15), r5 - mov.l @(OFF_R6,r15), r6 - mov.l @(OFF_R7,r15), r7 ! arg3 - mov.l @(OFF_R3,r15), r3 ! syscall_nr - ! Arrange for syscall_trace() to be called - ! again as the system call returns. - mov.l __syscall_ret_trace, r10 - bra 6f - lds r10, pr - ! No it isn't traced. - ! Arrange for normal system call return. -5: mov.l __syscall_ret, r10 - lds r10, pr - ! Call the system call handler through the table. - ! (both normal and ptrace'd) - ! First check for bad syscall number -6: mov r3, r9 - mov.l __n_sys, r10 - cmp/hs r10, r9 - bf 2f - ! Bad syscall number - rts ! go to syscall_ret or syscall_ret_trace - mov #-ENOSYS, r0 - ! Good syscall number -2: shll2 r9 ! x4 - mov.l __sct, r11 - add r11, r9 - mov.l @r9, r11 - jmp @r11 ! jump to specific syscall handler - nop - - ! In case of trace -syscall_ret_trace: - mov.l r0, @(OFF_R0,r15) ! save the return value - mov.l __syscall_trace, r1 - mova SYMBOL_NAME(ret_from_syscall), r0 - jmp @r1 ! Call syscall_trace() which notifies superior - lds r0, pr ! Then return to ret_from_syscall() - - - -#ifdef COMPAT_OLD_SYSCALL_ABI -! Handle old ABI system call. -! Note that ptrace(SYSCALL) is not supported for the old ABI. -! At this point: -! r0, r4-7 as per ABI -! r8 = value of TRA register (= num_args<<2) -! r14 = points to SYSCALL_NR in stack frame -old_abi_system_call: - mov r0, r9 ! Save system call number in r9 - ! ! arrange for return which pops stack - mov.l __old_abi_syscall_ret, r10 - lds r10, pr - ! Build the stack frame if TRA > 0 - mov r8, r10 - cmp/pl r10 - bf 0f - mov.l @(OFF_SP,r15), r0 ! get original user stack -7: add #-4, r10 -4: mov.l @(r0,r10), r1 ! May cause address error exception.. - mov.l r1, @-r15 - cmp/pl r10 - bt 7b -0: - mov.l r9, @r14 ! set syscall_nr + mov.l r8, @r9 ! set TRA value to tra STI() ! Call the system call handler through the table. ! First check for bad syscall number - mov.l __n_sys, r10 - cmp/hs r10, r9 - bf 2f - ! Bad syscall number - rts ! return to old_abi_syscall_ret - mov #-ENOSYS, r0 - ! Good syscall number -2: shll2 r9 ! x4 - mov.l __sct, r11 - add r11, r9 - mov.l @r9, r11 - jmp @r11 ! call specific syscall handler, - nop - - .align 2 -__old_abi_syscall_ret: - .long old_abi_syscall_ret - - ! This code gets called on address error exception when copying - ! syscall arguments from user stack to kernel stack. It is - ! supposed to return -EINVAL through old_abi_syscall_ret, but it - ! appears to have been broken for a long time in that the r0 - ! return value will be saved into the kernel stack relative to r15 - ! but the value of r15 is not correct partway through the loop. - ! So the user prog is returned its old r0 value, not -EINVAL. - ! Greg Banks 28 Aug 2000. - .section .fixup,"ax" -fixup_syscall_argerr: - ! First get r15 back to - rts - mov #-EINVAL, r0 - .previous - - .section __ex_table, "a" - .align 2 - .long 4b,fixup_syscall_argerr - .previous -#endif - - .align 2 -__TRA: .long TRA -__syscall_trace: -#error .long SYMBOL_NAME(syscall_trace) -__n_sys:.long NR_syscalls -__sct: .long SYMBOL_NAME(sys_call_table) -__syscall_ret_trace: - .long syscall_ret_trace -__syscall_ret: - .long syscall_ret -__INV_IMASK: - .long 0xffffff0f ! ~(IMASK) - - - .align 2 -reschedule: - mova SYMBOL_NAME(ret_from_syscall), r0 - mov.l 1f, r1 - jmp @r1 - lds r0, pr - .align 2 -1: .long SYMBOL_NAME(schedule) - -ret_from_irq: -ret_from_exception: - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - bt restore_all ! Yes, it's from kernel, go back soon - ! - bra ret_from_syscall + mov r3, r9 + mov.l 2f, r8 ! Number of syscalls + cmp/hs r8, r9 + bf/s good_system_call + GET_THREAD_INFO(r8) +syscall_badsys: ! Bad syscall number + mov #-ENOSYS, r0 + bra resume_userspace + mov.l r0, @(OFF_R0,r15) ! Return value + ! +good_system_call: ! Good syscall number + mov.l @(TI_FLAGS,r8), r8 + mov #_TIF_SYSCALL_TRACE, r10 + tst r10, r8 + bf syscall_trace_entry + ! +syscall_call: + shll2 r9 ! x4 + mov.l 3f, r8 ! Load the address of sys_call_table + add r8, r9 + mov.l @r9, r8 + jsr @r8 ! jump to specific syscall handler nop - - .align 2 -#ifdef COMPAT_OLD_SYSCALL_ABI -old_abi_syscall_ret: - add r8, r15 ! pop off the arguments - /* fall through */ -#endif -syscall_ret: - mov.l r0, @(OFF_R0,r15) ! save the return value - /* fall through */ - -ENTRY(ret_from_syscall) + mov.l r0, @(OFF_R0,r15) ! save the return value + .globl ret_from_fork +ret_from_fork: +syscall_exit: /* CLI */ stc sr, r0 or #0xf0, r0 ldc r0, sr ! - stc k_current, r1 -#error mov.l @(need_resched,r1), r0 - tst r0, r0 - bf reschedule -#error mov.l @(sigpending,r1), r0 - tst r0, 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 - .align 2 -__do_signal: -#error .long SYMBOL_NAME(do_signal) -__irq_stat: - .long SYMBOL_NAME(irq_stat) - - .align 2 + GET_THREAD_INFO(r8) + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_ALLWORK_MASK, r0 + bf syscall_exit_work restore_all: mov.l @r15+, r0 mov.l @r15+, r1 @@ -576,8 +460,8 @@ restore_all: mov.l @r15+, r7 ! stc sr, r8 - mov.l __blrb_flags, r9 ! BL =1, RB=1 - or r9, r8 + mov.l 7f, r9 + or r9, r8 ! BL =1, RB=1 ldc r8, sr ! here, change the register bank ! mov.l @r15+, r8 @@ -598,10 +482,10 @@ restore_all: ! ! Calculate new SR value mov k3, k2 ! original SR value - mov.l 1f, k1 + mov.l 8f, k1 stc sr, k0 and k1, k0 ! Get current FD-bit - mov.l 2f, k1 + mov.l 9f, k1 and k1, k2 ! Mask orignal SR value or k0, k2 ! Inherit current FD-bit ! @@ -609,11 +493,11 @@ restore_all: shlr2 k0 and #0x3c, k0 cmp/eq #0x3c, k0 - bt/s 7f + bt/s 6f shll2 k0 mov g_imask, k0 ! -7: or k0, k2 ! Set the IMASK-bits +6: or k0, k2 ! Set the IMASK-bits ldc k2, ssr ! mov k4, r15 @@ -621,10 +505,15 @@ restore_all: nop .align 2 -__blrb_flags: .long 0x30000000 -1: .long 0x00008000 ! FD -2: .long 0xffff7f0f ! ~(IMASK+FD) -3: .long 0x00080000 ! SZ=0, PR=1 +1: .long TRA +2: .long NR_syscalls +3: .long SYMBOL_NAME(sys_call_table) +4: .long SYMBOL_NAME(do_syscall_trace) +7: .long 0x30000000 +8: .long 0x00008000 ! FD +9: .long 0xffff7f0f ! ~(IMASK+FD) +__INV_IMASK: + .long 0xffffff0f ! ~(IMASK) ! Exception Vector Base ! @@ -641,8 +530,8 @@ general_exception: bra handle_exception mov.l @k2, k2 .align 2 -2: .long ret_from_exception 1: .long EXPEVT +2: .long ret_from_exception ! ! .balign 1024,0,1024 @@ -667,6 +556,7 @@ interrupt: ! ! + .align 2 handle_exception: ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. @@ -674,18 +564,18 @@ handle_exception: stc ssr, k0 ! Is it from kernel space? shll k0 ! Check MD bit (bit30) by shifting it into... shll k0 ! ...the T bit - bt/s 9f ! It's a kernel to kernel transition. + bt/s 1f ! It's a kernel to kernel transition. mov r15, k0 ! save original stack to k0 /* User space to kernel */ mov #0x20, k1 - shll8 k1 ! k1 <= 8192 == THREAD_SIZE + shll8 k1 ! k1 := 8192 (== THREAD_SIZE) add current, k1 mov k1, r15 ! change to kernel stack ! -9: mov #-1, k4 - mov.l 3f, k1 +1: mov #-1, k4 + mov.l 2f, k1 ! Save the user registers on the stack. - mov.l k4, @-r15 ! syscall_nr (default: -1) + mov.l k4, @-r15 ! set TRA (default: -1) ! sts.l macl, @-r15 sts.l mach, @-r15 @@ -707,7 +597,7 @@ handle_exception: ! stc sr, r8 ! Back to normal register bank, and or k1, r8 ! Block all interrupts - mov.l 5f, k1 + mov.l 3f, k1 and k1, r8 ! ... ldc r8, sr ! ...changed here. ! @@ -723,17 +613,18 @@ handle_exception: stc k_ex_code, r8 shlr2 r8 shlr r8 - mov.l 1f, r9 + mov.l 4f, r9 add r8, r9 mov.l @r9, r9 jmp @r9 nop + .align 2 -1: .long SYMBOL_NAME(exception_handling_table) -3: .long 0x000000f0 ! FD=0, IMASK=15 -5: .long 0xcfffffff ! RB=0, BL=0 -6: .long 0x00080000 ! SZ=0, PR=1 +2: .long 0x000000f0 ! FD=0, IMASK=15 +3: .long 0xcfffffff ! RB=0, BL=0 +4: .long SYMBOL_NAME(exception_handling_table) + .align 2 none: rts nop @@ -1195,16 +1086,27 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_madvise) .long SYMBOL_NAME(sys_getdents64) /* 220 */ .long SYMBOL_NAME(sys_fcntl64) + .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */ + .long SYMBOL_NAME(sys_ni_syscall) /* Reserved for Security */ .long SYMBOL_NAME(sys_gettid) + .long SYMBOL_NAME(sys_readahead) /* 225 */ + .long SYMBOL_NAME(sys_setxattr) + .long SYMBOL_NAME(sys_lsetxattr) + .long SYMBOL_NAME(sys_fsetxattr) + .long SYMBOL_NAME(sys_getxattr) + .long SYMBOL_NAME(sys_lgetxattr) /* 230 */ + .long SYMBOL_NAME(sys_fgetxattr) + .long SYMBOL_NAME(sys_listxattr) + .long SYMBOL_NAME(sys_llistxattr) + .long SYMBOL_NAME(sys_flistxattr) + .long SYMBOL_NAME(sys_removexattr) /* 235 */ + .long SYMBOL_NAME(sys_lremovexattr) + .long SYMBOL_NAME(sys_fremovexattr) .long SYMBOL_NAME(sys_tkill) + .long SYMBOL_NAME(sys_sendfile64) + .long SYMBOL_NAME(sys_futex) /* 240 */ - /* - * NOTE!! This doesn't have to be exact - we just have - * to make sure we have _enough_ of the "sys_ni_syscall" - * entries. Don't panic if you notice that this hasn't - * been shrunk every time we add a new system call. - */ - .rept NR_syscalls-221 + .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/fpu.c linux-2.5.8-pre1.superh/arch/sh/kernel/fpu.c --- linux-2.5.8-pre1/arch/sh/kernel/fpu.c Mon Feb 11 10:50:07 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/fpu.c Fri Mar 22 21:35:26 2002 @@ -67,7 +67,7 @@ save_fpu(struct task_struct *tsk) "r" (FPSCR_INIT) : "memory"); - tsk->flags &= ~PF_USEDFPU; + clear_tsk_thread_flag(tsk, TIF_USEDFPU); release_fpu(); } @@ -260,7 +260,7 @@ ieee_fpe_handler (struct pt_regs *regs) ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); grab_fpu(); restore_fpu(tsk); - tsk->flags |= PF_USEDFPU; + set_tsk_thread_flag(tsk, TIF_USEDFPU); } else { tsk->thread.trap_no = 11; tsk->thread.error_code = 0; @@ -310,5 +310,5 @@ do_fpu_state_restore(unsigned long r4, u fpu_init(); tsk->used_math = 1; } - tsk->flags |= PF_USEDFPU; + set_tsk_thread_flag(tsk, TIF_USEDFPU); } diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/head.S linux-2.5.8-pre1.superh/arch/sh/kernel/head.S --- linux-2.5.8-pre1/arch/sh/kernel/head.S Mon Feb 11 10:50:16 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/head.S Fri Mar 22 21:57:10 2002 @@ -48,7 +48,7 @@ ENTRY(_stext) mov #0x20, r1 ! shll8 r1 ! r1 = 8192 sub r1, r0 ! - ldc r0, r7_bank ! ... and init_task + ldc r0, r7_bank ! ... and initial thread_info ! ! Enable cache mov.l 6f, r0 diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/init_task.c linux-2.5.8-pre1.superh/arch/sh/kernel/init_task.c --- linux-2.5.8-pre1/arch/sh/kernel/init_task.c Mon Feb 11 10:50:10 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/init_task.c Tue Feb 26 19:08:42 2002 @@ -12,12 +12,19 @@ static struct signal_struct init_signals struct mm_struct init_mm = INIT_MM(init_mm); /* - * Initial task structure. + * Initial thread structure. * * We need to make sure that this is 8192-byte aligned due to the * way process stacks are handled. This is done by having a special * "init_task" linker map entry.. */ -union task_union init_task_union +union thread_union init_thread_union __attribute__((__section__(".data.init_task"))) = - { INIT_TASK(init_task_union.task) }; + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/io_7751se.c linux-2.5.8-pre1.superh/arch/sh/kernel/io_7751se.c --- linux-2.5.8-pre1/arch/sh/kernel/io_7751se.c Mon Feb 11 10:50:09 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/io_7751se.c Mon Jan 21 08:48:19 2002 @@ -97,7 +97,7 @@ shifted_port(unsigned long port) #define CHECK_SH7751_PCIIO(port) \ ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) #else -#define CHECK_SH_7751_PCIIO(port) (0) +#define CHECK_SH7751_PCIIO(port) (0) #endif /* diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/io_se.c linux-2.5.8-pre1.superh/arch/sh/kernel/io_se.c --- linux-2.5.8-pre1/arch/sh/kernel/io_se.c Mon Feb 11 10:50:07 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/io_se.c Tue Feb 26 18:15:15 2002 @@ -22,6 +22,7 @@ int sh_pcic_io_dummy; static inline void delay(void) { + ctrl_inw(0xa0000000); ctrl_inw(0xa0000000); } diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/pci-dma.c linux-2.5.8-pre1.superh/arch/sh/kernel/pci-dma.c --- linux-2.5.8-pre1/arch/sh/kernel/pci-dma.c Mon Feb 11 10:50:11 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/pci-dma.c Tue Feb 26 19:10:20 2002 @@ -26,7 +26,7 @@ void *pci_alloc_consistent(struct pci_de if (ret != NULL) { /* Is it neccessary to do the memset? */ memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); + *dma_handle = virt_to_phys(ret); } /* We must flush the cache before we pass it on to the device */ dma_cache_wback_inv(ret, size); diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/process.c linux-2.5.8-pre1.superh/arch/sh/kernel/process.c --- linux-2.5.8-pre1/arch/sh/kernel/process.c Mon Feb 11 10:50:11 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/process.c Fri Mar 29 09:02:04 2002 @@ -43,8 +43,9 @@ void cpu_idle(void *unused) /* endless idle loop with no priority at all */ while (1) { if (hlt_counter) { - if (need_resched()) - break; + while (1) + if (need_resched()) + break; } else { __cli(); while (!need_resched()) { @@ -55,7 +56,6 @@ void cpu_idle(void *unused) __sti(); } schedule(); - check_pgt_cache(); } } @@ -97,17 +97,6 @@ void show_regs(struct pt_regs * regs) regs->mach, regs->macl, regs->gbr, regs->pr); } -struct task_struct * alloc_task_struct(void) -{ - /* Get two pages */ - return (struct task_struct *) __get_free_pages(GFP_KERNEL,1); -} - -void free_task_struct(struct task_struct *p) -{ - free_pages((unsigned long) p, 1); -} - /* * Create a kernel thread */ @@ -177,11 +166,7 @@ int dump_fpu(struct pt_regs *regs, elf_f fpvalid = tsk->used_math; if (fpvalid) { - unsigned long flags; - - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); } @@ -198,26 +183,14 @@ int copy_thread(int nr, unsigned long cl struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; -#if defined(__SH4__) - struct task_struct *tsk = current; - - if (tsk != &init_task) { - unsigned long flags; - save_and_cli(flags); - unlazy_fpu(tsk); - restore_flags(flags); - p->thread.fpu = current->thread.fpu; - p->used_math = tsk->used_math; - } -#endif - childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1; + childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p->thread_info)) - 1; *childregs = *regs; if (user_mode(regs)) { childregs->regs[15] = usp; } else { - childregs->regs[15] = (unsigned long)p+2*PAGE_SIZE; + childregs->regs[15] = (unsigned long)p->thread_info+THREAD_SIZE; } childregs->regs[0] = 0; /* Set return value for child */ childregs->sr |= SR_FD; /* Invalidate FPU flag */ @@ -225,6 +198,16 @@ int copy_thread(int nr, unsigned long cl p->thread.sp = (unsigned long) childregs; p->thread.pc = (unsigned long) ret_from_fork; +#if defined(__SH4__) + { + struct task_struct *tsk = current; + + unlazy_fpu(tsk); + p->thread.fpu = tsk->thread.fpu; + p->used_math = tsk->used_math; + clear_ti_thread_flag(p->thread_info, TIF_USEDFPU); + } +#endif return 0; } @@ -255,13 +238,7 @@ void dump_thread(struct pt_regs * regs, void __switch_to(struct task_struct *prev, struct task_struct *next) { #if defined(__SH4__) - if (prev != &init_task) { - unsigned long flags; - - save_and_cli(flags); - unlazy_fpu(prev); - restore_flags(flags); - } + unlazy_fpu(prev); #endif /* * Restore the kernel mode register @@ -269,7 +246,7 @@ void __switch_to(struct task_struct *pre */ asm volatile("ldc %0, r7_bank" : /* no output */ - :"r" (next)); + : "r" (next->thread_info)); } asmlinkage int sys_fork(unsigned long r4, unsigned long r5, @@ -347,23 +324,12 @@ unsigned long get_wchan(struct task_stru /* * The same comment as on the Alpha applies here, too ... */ - pc = thread_saved_pc(&p->thread); + pc = thread_saved_pc(p); if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) { schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; return (unsigned long)((unsigned long *)schedule_frame)[1]; } return pc; -} - -asmlinkage void print_syscall(int x) -{ - unsigned long flags, sr; - asm("stc sr, %0": "=r" (sr)); - save_and_cli(flags); - printk("%c: %c %c, %c: SYSCALL\n", (x&63)+32, - (current->flags&PF_USEDFPU)?'C':' ', - (init_task.flags&PF_USEDFPU)?'K':' ', (sr&SR_FD)?' ':'F'); - restore_flags(flags); } asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/ptrace.c linux-2.5.8-pre1.superh/arch/sh/kernel/ptrace.c --- linux-2.5.8-pre1/arch/sh/kernel/ptrace.c Mon Feb 11 10:50:10 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/ptrace.c Fri Mar 22 21:57:10 2002 @@ -159,7 +159,7 @@ void ptrace_disable(struct task_struct * asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { - struct task_struct *child, *tsk = current; + struct task_struct *child; struct user * dummy = NULL; int ret; @@ -191,15 +191,11 @@ asmlinkage int sys_ptrace(long request, ret = ptrace_attach(child); goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; - } - if (child->p_pptr != tsk) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; + switch (request) { /* when I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -279,9 +275,9 @@ asmlinkage int sys_ptrace(long request, if ((unsigned long) data > _NSIG) break; if (request == PTRACE_SYSCALL) - child->ptrace |= PT_TRACESYS; + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); else - child->ptrace &= ~PT_TRACESYS; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; wake_up_process(child); ret = 0; @@ -312,7 +308,7 @@ asmlinkage int sys_ptrace(long request, ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~PT_TRACESYS; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); if ((child->ptrace & PT_DTRACE) == 0) { /* Spurious delayed TF traps may occur */ child->ptrace |= PT_DTRACE; @@ -370,22 +366,23 @@ asmlinkage int sys_ptrace(long request, break; } out_tsk: - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); return ret; } -asmlinkage void syscall_trace(void) +asmlinkage void do_syscall_trace(void) { struct task_struct *tsk = current; - if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYS)) - != (PT_PTRACED|PT_TRACESYS)) + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(tsk->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ - tsk->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + tsk->exit_code = SIGTRAP | ((tsk->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0); tsk->state = TASK_STOPPED; notify_parent(tsk, SIGCHLD); diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/setup.c linux-2.5.8-pre1.superh/arch/sh/kernel/setup.c --- linux-2.5.8-pre1/arch/sh/kernel/setup.c Mon Feb 11 10:50:09 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/setup.c Fri Mar 22 21:57:10 2002 @@ -474,9 +474,9 @@ void __init setup_arch(char **cmdline_p) } #if defined(__SH4__) - /* We already grab/initialized FPU in head.S. Make it consisitent. */ - init_task.used_math = 1; - init_task.flags |= PF_USEDFPU; + /* FPU initialization */ + clear_thread_flag(TIF_USEDFPU); + current->used_math = 0; #endif paging_init(); } diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/sh_ksyms.c linux-2.5.8-pre1.superh/arch/sh/kernel/sh_ksyms.c --- linux-2.5.8-pre1/arch/sh/kernel/sh_ksyms.c Thu Apr 4 18:09:30 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/sh_ksyms.c Thu Apr 4 17:39:13 2002 @@ -36,9 +36,6 @@ EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(no_irq_type); -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy); - EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strlen); @@ -81,7 +78,7 @@ EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__const_udelay); #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name) - + /* These symbols are generated by the compiler itself */ DECLARE_EXPORT(__udivsi3); DECLARE_EXPORT(__sdivsi3); diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/signal.c linux-2.5.8-pre1.superh/arch/sh/kernel/signal.c --- linux-2.5.8-pre1/arch/sh/kernel/signal.c Fri Mar 22 10:09:01 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/signal.c Fri Mar 29 09:02:04 2002 @@ -198,27 +198,20 @@ static inline int restore_sigcontext_fpu static inline int save_sigcontext_fpu(struct sigcontext *sc) { struct task_struct *tsk = current; - unsigned long flags; - int val; if (!tsk->used_math) { - val = 0; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(0, &sc->sc_ownedfp); return 0; } - val = 1; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(1, &sc->sc_ownedfp); /* This will cause a "finit" to be triggered by the next attempted FPU operation by the 'current' process. */ tsk->used_math = 0; - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); - return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, sizeof(long)*(16*2+2)); } @@ -250,14 +243,14 @@ restore_sigcontext(struct pt_regs *regs, regs->sr |= SR_FD; /* Release FPU */ clear_fpu(tsk); - current->used_math = 0; + tsk->used_math = 0; __get_user (owned_fp, &sc->sc_ownedfp); if (owned_fp) err |= restore_sigcontext_fpu(sc); } #endif - regs->syscall_nr = -1; /* disable syscall checks */ + regs->tra = -1; /* disable syscall checks */ err |= __get_user(*r0_p, &sc->sc_regs[0]); return err; } @@ -390,10 +383,10 @@ static void setup_frame(int sig, struct if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - signal = current->exec_domain - && current->exec_domain->signal_invmap + signal = current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap && sig < 32 - ? current->exec_domain->signal_invmap[sig] + ? current_thread_info()->exec_domain->signal_invmap[sig] : sig; err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); @@ -455,10 +448,10 @@ static void setup_rt_frame(int sig, stru if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - signal = current->exec_domain - && current->exec_domain->signal_invmap + signal = current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap && sig < 32 - ? current->exec_domain->signal_invmap[sig] + ? current_thread_info()->exec_domain->signal_invmap[sig] : sig; err |= __put_user(&frame->info, &frame->pinfo); @@ -526,7 +519,7 @@ handle_signal(unsigned long sig, struct siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { /* Are we from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->tra >= 0) { /* If so, check system call restarting.. */ switch (regs->regs[0]) { case -ERESTARTNOHAND: @@ -540,7 +533,6 @@ handle_signal(unsigned long sig, struct } /* fallthrough */ case -ERESTARTNOINTR: - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } @@ -620,8 +612,8 @@ int do_signal(struct pt_regs *regs, sigs info.si_signo = signr; info.si_errno = 0; info.si_code = SI_USER; - info.si_pid = current->p_pptr->pid; - info.si_uid = current->p_pptr->uid; + info.si_pid = current->parent->pid; + info.si_uid = current->parent->uid; } /* If the (new) signal is now blocked, requeue it. */ @@ -660,7 +652,7 @@ int do_signal(struct pt_regs *regs, sigs case SIGSTOP: current->state = TASK_STOPPED; current->exit_code = signr; - if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + if (!(current->parent->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); continue; @@ -684,12 +676,11 @@ int do_signal(struct pt_regs *regs, sigs } /* Did we come from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->tra >= 0) { /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/time.c linux-2.5.8-pre1.superh/arch/sh/kernel/time.c --- linux-2.5.8-pre1/arch/sh/kernel/time.c Mon Feb 11 10:50:07 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/time.c Thu Mar 28 10:39:32 2002 @@ -175,6 +175,25 @@ void do_settimeofday(struct timeval *tv) /* last time the RTC clock got updated */ static long last_rtc_update; + +static __inline__ void sh_do_profile (unsigned long pc) +{ + extern int _stext; + + if (!prof_buffer) + return; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len-1) + pc = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[pc]); +} /* * timer_interrupt() needs to keep up the real-time clock, diff -ru3pN linux-2.5.8-pre1/arch/sh/kernel/traps.c linux-2.5.8-pre1.superh/arch/sh/kernel/traps.c --- linux-2.5.8-pre1/arch/sh/kernel/traps.c Mon Feb 11 10:50:08 2002 +++ linux-2.5.8-pre1.superh/arch/sh/kernel/traps.c Tue Mar 5 15:12:22 2002 @@ -1,10 +1,11 @@ -/* $Id: traps.c,v 1.14 2001/07/24 08:07:10 gniibe Exp $ +/* $Id: traps.c,v 1.15 2002/03/01 07:47:11 lethal Exp $ * * linux/arch/sh/traps.c * * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells + * Copyright (C) 2002 Paul Mundt */ /* @@ -560,29 +561,51 @@ void __init trap_init(void) : "memory"); } -void dump_stack(void) +void show_task(unsigned long *sp) { - unsigned long *start; - unsigned long *end; - unsigned long *p; - - asm("mov r15, %0" : "=r" (start)); - asm("stc r7_bank, %0" : "=r" (end)); - end += 8192/4; - - printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end); - for (p=start; p < end; p++) { - extern long _text, _etext; - unsigned long v=*p; - - if ((v >= (unsigned long )&_text) - && (v <= (unsigned long )&_etext)) { - printk("%08lx\n", v); + unsigned long *stack, addr; + unsigned long module_start = VMALLOC_START; + unsigned long module_end = VMALLOC_END; + extern long _text, _etext; + int i = 1; + + if (!sp) { + __asm__ __volatile__ ( + "mov r15, %0\n\t" + "stc r7_bank, %1\n\t" + : "=r" (module_start), + "=r" (module_end) + ); + + sp = (unsigned long *)module_start; + } + + stack = sp; + + printk("\nCall trace: "); + + while (((long)stack & (THREAD_SIZE - 1))) { + if (__get_user(addr, stack)) { + printk("Failing address 0x%lx\n", *stack); + break; + } + stack++; + + if (((addr >= (unsigned long)&_text) && + (addr <= (unsigned long)&_etext)) || + ((addr >= module_start) && (addr <= module_end))) { + if (i && ((i % 8) == 0)) + printk("\n "); + + printk("[<%08lx>] ", addr); + i++; } } + + printk("\n"); } void show_trace_task(struct task_struct *tsk) { - printk("Backtrace not yet implemented for SH.\n"); + show_task((unsigned long *)tsk->thread.sp); } diff -ru3pN linux-2.5.8-pre1/arch/sh/lib/Makefile linux-2.5.8-pre1.superh/arch/sh/lib/Makefile --- linux-2.5.8-pre1/arch/sh/lib/Makefile Mon Feb 11 10:50:17 2002 +++ linux-2.5.8-pre1.superh/arch/sh/lib/Makefile Mon Mar 25 19:20:22 2002 @@ -3,7 +3,7 @@ # L_TARGET = lib.a -obj-y = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ +obj-y = delay.o memcpy.o memset.o memmove.o memchr.o \ checksum.o strcasecmp.o strlen.o USE_STANDARD_AS_RULE := true diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/Makefile linux-2.5.8-pre1.superh/arch/sh/mm/Makefile --- linux-2.5.8-pre1/arch/sh/mm/Makefile Mon Feb 11 10:50:14 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/Makefile Wed Mar 27 14:08:50 2002 @@ -11,7 +11,7 @@ O_TARGET := mm.o obj-y := init.o fault.o extable.o clear_page.o copy_page.o obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o +obj-$(CONFIG_CPU_SH4) += cache-sh4.o ioremap.o USE_STANDARD_AS_RULE := true diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/__clear_user_page-sh4.S linux-2.5.8-pre1.superh/arch/sh/mm/__clear_user_page-sh4.S --- linux-2.5.8-pre1/arch/sh/mm/__clear_user_page-sh4.S Mon Feb 11 10:50:09 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/__clear_user_page-sh4.S Thu Jan 1 09:00:00 1970 @@ -1,49 +0,0 @@ -/* $Id$ - * - * __clear_user_page implementation of SuperH - * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima - * - */ - -/* - * __clear_user_page - * @to: P1 address (with same color) - * @orig_to: P1 address - * - * void __clear_user_page(void *to, void *orig_to) - */ - -/* - * r0 --- scratch - * r4 --- to - * r5 --- orig_to - * r6 --- to + 4096 - */ -#include <linux/linkage.h> -ENTRY(__clear_user_page) - mov r4,r6 - mov.w .L4096,r0 - add r0,r6 - mov #0,r0 - ! -1: ocbi @r5 - add #32,r5 - movca.l r0,@r4 - mov r4,r1 - add #32,r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - add #28,r4 - cmp/eq r6,r4 - bf/s 1b - ocbwb @r1 - ! - rts - nop -.L4096: .word 4096 diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/__copy_user_page-sh4.S linux-2.5.8-pre1.superh/arch/sh/mm/__copy_user_page-sh4.S --- linux-2.5.8-pre1/arch/sh/mm/__copy_user_page-sh4.S Mon Feb 11 10:50:07 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/__copy_user_page-sh4.S Thu Jan 1 09:00:00 1970 @@ -1,69 +0,0 @@ -/* $Id: __copy_user_page-sh4.S,v 1.1 2001/07/23 09:02:17 gniibe Exp $ - * - * __copy_user_page implementation of SuperH - * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima - * - */ - -/* - * __copy_user_page - * @to: P1 address (with same color) - * @from: P1 address - * @orig_to: P1 address - * - * void __copy_user_page(void *to, void *from, void *orig_to) - */ - -/* - * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch - * r8 --- from + 4096 - * r9 --- orig_to - * r10 --- to - * r11 --- from - */ -#include <linux/linkage.h> -ENTRY(__copy_user_page) - mov.l r8,@-r15 - mov.l r9,@-r15 - mov.l r10,@-r15 - mov.l r11,@-r15 - mov r4,r10 - mov r5,r11 - mov r6,r9 - mov r5,r8 - mov.w .L4096,r0 - add r0,r8 - ! -1: ocbi @r9 - add #32,r9 - mov.l @r11+,r0 - mov.l @r11+,r1 - mov.l @r11+,r2 - mov.l @r11+,r3 - mov.l @r11+,r4 - mov.l @r11+,r5 - mov.l @r11+,r6 - mov.l @r11+,r7 - movca.l r0,@r10 - mov r10,r0 - add #32,r10 - mov.l r7,@-r10 - mov.l r6,@-r10 - mov.l r5,@-r10 - mov.l r4,@-r10 - mov.l r3,@-r10 - mov.l r2,@-r10 - mov.l r1,@-r10 - ocbwb @r0 - cmp/eq r11,r8 - bf/s 1b - add #28,r10 - ! - mov.l @r15+,r11 - mov.l @r15+,r10 - mov.l @r15+,r9 - mov.l @r15+,r8 - rts - nop -.L4096: .word 4096 diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/cache-sh4.c linux-2.5.8-pre1.superh/arch/sh/mm/cache-sh4.c --- linux-2.5.8-pre1/arch/sh/mm/cache-sh4.c Mon Feb 11 10:50:11 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/cache-sh4.c Wed Apr 3 11:38:34 2002 @@ -1,9 +1,9 @@ -/* $Id: cache-sh4.c,v 1.16 2001/09/10 11:06:35 dwmw2 Exp $ +/* $Id: cache-sh4.c,v 1.17 2002/04/03 02:38:34 gniibe Exp $ * - * linux/arch/sh/mm/cache.c - * - * Copyright (C) 1999, 2000 Niibe Yutaka + * linux/arch/sh/mm/cache-sh4.c * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka + * Copyright (C) 2001, 2002 Paul Mundt */ #include <linux/config.h> @@ -109,7 +109,7 @@ void __init p3_cache_init(void) unsigned long size, unsigned long flags); if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) - panic("p3_cachie_init failed."); + panic("%s failed.", __FUNCTION__); sema_init (&p3map_sem[0], 1); sema_init (&p3map_sem[1], 1); sema_init (&p3map_sem[2], 1); @@ -208,44 +208,64 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } -/* - * Writeback&Invalidate the D-cache of the page - */ -static void __flush_dcache_page(unsigned long phys) +static void flush_cache_4096_all(unsigned long start) { - unsigned long addr, data; - unsigned long flags; - - phys |= CACHE_VALID; - - save_and_cli(flags); - jump_to_P2(); - - /* Loop all the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY; - addr < (CACHE_OC_ADDRESS_ARRAY - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } +#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr; + for (addr = start; addr < start + 4096; addr += 32) + ctrl_outl(0, addr); +#else + register unsigned long __r0 __asm__ ("r0") = 0; + register unsigned long __r1 __asm__ ("r1") = 128; + register unsigned long __r4 __asm__ ("r4"); + register unsigned long __r5 __asm__ ("r5"); + register unsigned long __r6 __asm__ ("r6"); + register unsigned long __r7 __asm__ ("r7"); + extern void __flush_cache_4096_all(unsigned long); + + asm volatile("jsr @%7; nop" + : "=&r" (__r4), "=&r" (__r5), "=&r" (__r6), "=&r" (__r7) + : "0" (start), "r" (__r0), "r" (__r1), + "r" (__flush_cache_4096_all + 0x20000000) + : "pr"); +#endif +} -#if 0 /* DEBUG DEBUG */ - /* Loop all the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY; - addr < (CACHE_IC_ADDRESS_ARRAY - +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) { - printk(KERN_INFO "__flush_cache_page: I-cache entry found\n"); - ctrl_outl(0, addr); +static inline void flush_cache_4096(unsigned long start, + unsigned long phys) +{ +#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) + if (start >= CACHE_OC_ADDRESS_ARRAY) { + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr, data; + for (addr = start; addr < start + 4096; addr += 32) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); } - } + } else #endif - back_to_P1(); - restore_flags(flags); + { + register unsigned long addr __asm__ ("r4"); + register unsigned long data __asm__ ("r0"); + register unsigned long __r5 __asm__ ("r5") = phys; + register unsigned long __r6 __asm__ ("r6") = (0x1ffff000|CACHE_VALID); + register unsigned long __r7 __asm__ ("r7") = 0; + extern void __flush_cache_4096(unsigned long, unsigned long); + + asm volatile("jsr @%1; nop" + : "=r" (addr), "=r" (data) + : "0" (start), "1" (__flush_cache_4096 + 0x20000000), + "r" (__r5), "r" (__r6), "r" (__r7) + : "pr"); + } } /* @@ -254,38 +274,122 @@ static void __flush_dcache_page(unsigned */ void flush_dcache_page(struct page *page) { - if (test_bit(PG_mapped, &page->flags)) - __flush_dcache_page(PHYSADDR(page_address(page))); + if (test_bit(PG_mapped, &page->flags)) { + unsigned long phys = PHYSADDR(page_address(page)); + unsigned long flags; + + phys |= CACHE_VALID; + + save_and_cli(flags); + + /* Loop all the D-cache */ + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys); + + restore_flags(flags); + } } -void flush_cache_all(void) +static inline void flush_icache_all(void) { - extern unsigned long empty_zero_page[1024]; unsigned long flags; - unsigned long addr; save_and_cli(flags); + jump_to_P2(); + /* Flush I-cache */ + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); + back_to_P1(); + restore_flags(flags); +} + +#undef C_IMPLEMENTATION_OF_CACHE_ALL + +void flush_cache_all(void) +{ + extern unsigned long empty_zero_page[1024]; /* Prefetch the data to write back D-cache */ + +#ifdef C_IMPLEMENTATION_OF_CACHE_ALL + unsigned long addr; + for (addr = (unsigned long)empty_zero_page; addr < (unsigned long)empty_zero_page + 1024*16; addr += L1_CACHE_BYTES) asm volatile("pref @%0"::"r" (addr)); - - jump_to_P2(); - /* Flush D-cache/I-cache */ - ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_P1(); - restore_flags(flags); +#else + unsigned long a0, a1, a2, a3, cnt; + asm volatile( + "mov %0, %1; add #32, %1\n\t" + "mov %0, %2; add #64, %2\n\t" + "mov %1, %3; add #64, %3\n\t" + "1:\n\t" + "pref @%0\n\t" + "dt %4\n\t" + "pref @%1\n\t" + "add %5, %0\n\t" + "pref @%2\n\t" + "add %5, %1\n\t" + "pref @%3\n\t" + "add %5, %2\n\t" + "bf/s 1b\n\t" + " add %5, %3" + : "=&r" (a0), "=&r" (a1), "=&r" (a2), "=&r" (a3), "=&r" (cnt) + : "r" (32*4), "0" (empty_zero_page), "4" (1024*16/32/4) + : "t"); +#endif + flush_icache_all(); } void flush_cache_mm(struct mm_struct *mm) { /* Is there any good way? */ /* XXX: possibly call flush_cache_range for each vm area */ + /* + * FIXME: Really, the optimal solution here would be able to flush out + * individual lines created by the specified context, but this isn't + * feasible for a number of architectures (such as MIPS, and some + * SPARC) .. is this possible for SuperH? + * + * In the meantime, we'll just flush all of the caches.. this + * seems to be the simplest way to avoid at least a few wasted + * cache flushes. -Lethal + */ flush_cache_all(); } +static void __flush_cache_page(struct vm_area_struct *vma, + unsigned long address, + unsigned long phys) +{ + unsigned long flags; + + phys |= CACHE_VALID; + save_and_cli(flags); + + /* We only need to flush D-cache when we have alias */ + if ((address^phys) & CACHE_ALIAS) { + /* Loop 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), + phys); + /* Loop another 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), + phys); + } + + if (vma->vm_flags & VM_EXEC) + /* Loop 4K (half) of the I-cache */ + flush_cache_4096( + CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), + phys); + + restore_flags(flags); +} + /* * Write back and invalidate D-caches. * @@ -298,14 +402,52 @@ void flush_cache_mm(struct mm_struct *mm void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - /* - * We could call flush_cache_page for the pages of these range, - * but it's not efficient (scan the caches all the time...). - * - * We can't use A-bit magic, as there's the case we don't have - * valid entry on TLB. - */ - flush_cache_all(); + unsigned long p = start & PAGE_MASK; + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + unsigned long d = 0; + + dir = pgd_offset(vma->vm_mm, p); + pmd = pmd_offset(dir, p); + + do { + if (pmd_none(*pmd) || pmd_bad(*pmd)) { + p &= ~((1 << PMD_SHIFT) -1); + p += (1 << PMD_SHIFT); + pmd++; + continue; + } + pte = pte_offset_kernel(pmd, p); + do { + entry = *pte; + if ((pte_val(entry) & _PAGE_PRESENT)) { + phys = pte_val(entry)&PTE_PHYS_MASK; + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } + } + pte++; + p += PAGE_SIZE; + } while (p < end && (unsigned long)pte & PAGE_MASK); + pmd++; + } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY); + if (d & 2) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x1000); + if (d & 4) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x2000); + if (d & 8) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x3000); + if (vma->vm_flags & VM_EXEC) + flush_icache_all(); } /* @@ -319,58 +461,32 @@ void flush_cache_page(struct vm_area_str pmd_t *pmd; pte_t *pte; pte_t entry; - unsigned long phys, addr, data; - unsigned long flags; + unsigned long phys; dir = pgd_offset(vma->vm_mm, address); pmd = pmd_offset(dir, address); if (pmd_none(*pmd) || pmd_bad(*pmd)) return; - pte = pte_offset(pmd, address); + pte = pte_offset_kernel(pmd, address); entry = *pte; - if (pte_none(entry) || !pte_present(entry)) + if (!(pte_val(entry) & _PAGE_PRESENT)) return; phys = pte_val(entry)&PTE_PHYS_MASK; + __flush_cache_page(vma, address, phys); +} - phys |= CACHE_VALID; - save_and_cli(flags); - jump_to_P2(); - - /* We only need to flush D-cache when we have alias */ - if ((address^phys) & CACHE_ALIAS) { - /* Loop 4K of the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS); - addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) - +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - /* Loop another 4K of the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS); - addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) - +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - } - - if (vma->vm_flags & VM_EXEC) - /* Loop 4K of the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000); - addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000)) - +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - back_to_P1(); - restore_flags(flags); +/* + * flush_icache_user_range + * @vma: VMA of the process + * @page: page + * @addr: U0 address + * @len: length of the range (< page size) + */ +void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len) +{ + __flush_cache_page(vma, addr, PHYSADDR(page_address(page))); } /* @@ -394,7 +510,7 @@ void clear_user_page(void *to, unsigned unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *dir = pgd_offset_k(p3_addr); pmd_t *pmd = pmd_offset(dir, p3_addr); - pte_t *pte = pte_offset(pmd, p3_addr); + pte_t *pte = pte_offset_kernel(pmd, p3_addr); pte_t entry; unsigned long flags; @@ -433,7 +549,7 @@ void copy_user_page(void *to, void *from unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *dir = pgd_offset_k(p3_addr); pmd_t *pmd = pmd_offset(dir, p3_addr); - pte_t *pte = pte_offset(pmd, p3_addr); + pte_t *pte = pte_offset_kernel(pmd, p3_addr); pte_t entry; unsigned long flags; diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/clear_page.S linux-2.5.8-pre1.superh/arch/sh/mm/clear_page.S --- linux-2.5.8-pre1/arch/sh/mm/clear_page.S Mon Feb 11 10:50:12 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/clear_page.S Wed Apr 3 11:38:34 2002 @@ -1,10 +1,13 @@ -/* $Id: clear_page.S,v 1.1 2001/07/23 10:08:50 gniibe Exp $ +/* $Id: clear_page.S,v 1.5 2002/04/03 02:38:34 gniibe Exp $ * - * clear_page implementation of SuperH + * __clear_user_page, __clear_user, clear_page implementation of SuperH * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2001 Kaz Kojima + * Copyright (C) 2001, 2002 Niibe Yutaka * */ +#include <linux/config.h> +#include <linux/linkage.h> /* * clear_page @@ -18,7 +21,6 @@ * r4 --- to * r5 --- to + 4096 */ -#include <linux/linkage.h> ENTRY(clear_page) mov r4,r5 mov.w .Llimit,r0 @@ -50,3 +52,181 @@ ENTRY(clear_page) rts nop .Llimit: .word (4096-28) + +ENTRY(__clear_user) + ! + mov #0, r0 + mov #0xe0, r1 ! 0xffffffe0 + ! + ! r4..r4&~32 -------- not aligned [ Area 0 ] + ! r4&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] + ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] + ! + ! Clear area 0 + mov r4, r2 + and r1, r2 + cmp/eq r4, r2 + bt/s area1 + mov r4, r3 + sub r2, r3 + mov r4, r2 + ! +l0: dt r3 +0: mov.b r0, @r2 + bf/s l0 + add #1, r2 + ! + mov r4, r3 + add r5, r3 + and r1, r3 + ! + ! Clear area 1 +area1: +#if defined(__SH4__) +1: movca.l r0, @r2 +#else +1: mov.l r0, @r2 +#endif + add #4, r2 +2: mov.l r0, @r2 + add #4, r2 +3: mov.l r0, @r2 + add #4, r2 +4: mov.l r0, @r2 + add #4, r2 +5: mov.l r0, @r2 + add #4, r2 +6: mov.l r0, @r2 + add #4, r2 +7: mov.l r0, @r2 + add #4, r2 +8: mov.l r0, @r2 + add #4, r2 + cmp/hi r2, r3 + bt/s 1b + nop + ! + ! Clear area 2 + add r5, r4 + cmp/eq r4, r2 + bt/s done + sub r2, r4 +l2: dt r4 +9: mov.b r0, @r2 + bf/s l2 + add #1, r2 + ! +done: rts + nop ! return 0 as normal return + + ! return the number of bytes remained +bad_clear_user: + mov r4, r0 + mov r5, r0 + rts + sub r2, r0 + +.section __ex_table,"a" + .align 2 + .long 0b, bad_clear_user + .long 1b, bad_clear_user + .long 2b, bad_clear_user + .long 3b, bad_clear_user + .long 4b, bad_clear_user + .long 5b, bad_clear_user + .long 6b, bad_clear_user + .long 7b, bad_clear_user + .long 8b, bad_clear_user + .long 9b, bad_clear_user +.previous + +#if defined(__SH4__) +/* + * __clear_user_page + * @to: P1 address (with same color) + * @orig_to: P1 address + * + * void __clear_user_page(void *to, void *orig_to) + */ + +/* + * r0 --- scratch + * r4 --- to + * r5 --- orig_to + * r6 --- to + 4096 + */ +ENTRY(__clear_user_page) + mov.w .L4096,r0 + mov r4,r6 + add r0,r6 + mov #0,r0 + ! +1: ocbi @r5 + add #32,r5 + movca.l r0,@r4 + mov r4,r1 + add #32,r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + add #28,r4 + cmp/eq r6,r4 + bf/s 1b + ocbwb @r1 + ! + rts + nop +.L4096: .word 4096 + +ENTRY(__flush_cache_4096) + .rept 128 + mov.l @r4,r0 + and r6,r0 + cmp/eq r5,r0 + bf 1f + mov.l r7,@r4 +1: add #32,r4 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop + +#if defined(CONFIG_CPU_SUBTYPE_SH7750) +ENTRY(__flush_cache_4096_all) + mov r4,r5 + mov r4,r6 + mov r4,r7 + add #32,r5 + add #-64,r6 + add #-32,r7 + .rept 32 + mov.l r0,@r4 + add r1,r6 + mov.l r0,@r5 + add r1,r7 + mov.l r0,@r6 + add r1,r4 + mov.l r0,@r7 + add r1,r5 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop +#endif +#endif diff -ru3pN linux-2.5.8-pre1/arch/sh/mm/copy_page.S linux-2.5.8-pre1.superh/arch/sh/mm/copy_page.S --- linux-2.5.8-pre1/arch/sh/mm/copy_page.S Mon Feb 11 10:50:09 2002 +++ linux-2.5.8-pre1.superh/arch/sh/mm/copy_page.S Wed Apr 3 11:38:34 2002 @@ -1,10 +1,11 @@ -/* $Id: copy_page.S,v 1.2 2001/07/23 10:27:25 gniibe Exp $ +/* $Id: copy_page.S,v 1.3 2002/04/03 02:38:34 gniibe Exp $ * - * copy_page implementation of SuperH + * copy_page, __copy_user_page implementation of SuperH * * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima * */ +#include <linux/linkage.h> /* * copy_page @@ -21,7 +22,6 @@ * r10 --- to * r11 --- from */ -#include <linux/linkage.h> ENTRY(copy_page) mov.l r8,@-r15 mov.l r10,@-r15 @@ -66,4 +66,66 @@ ENTRY(copy_page) mov.l @r15+,r8 rts nop + +#if defined(__SH4__) +/* + * __copy_user_page + * @to: P1 address (with same color) + * @from: P1 address + * @orig_to: P1 address + * + * void __copy_user_page(void *to, void *from, void *orig_to) + */ + +/* + * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch + * r8 --- from + 4096 + * r9 --- orig_to + * r10 --- to + * r11 --- from + */ +ENTRY(__copy_user_page) + mov.l r8,@-r15 + mov.l r9,@-r15 + mov.l r10,@-r15 + mov.l r11,@-r15 + mov r4,r10 + mov r5,r11 + mov r6,r9 + mov r5,r8 + mov.w .L4096,r0 + add r0,r8 + ! +1: ocbi @r9 + add #32,r9 + mov.l @r11+,r0 + mov.l @r11+,r1 + mov.l @r11+,r2 + mov.l @r11+,r3 + mov.l @r11+,r4 + mov.l @r11+,r5 + mov.l @r11+,r6 + mov.l @r11+,r7 + movca.l r0,@r10 + mov r10,r0 + add #32,r10 + mov.l r7,@-r10 + mov.l r6,@-r10 + mov.l r5,@-r10 + mov.l r4,@-r10 + mov.l r3,@-r10 + mov.l r2,@-r10 + mov.l r1,@-r10 + oc... [truncated message content] |
From: NIIBE Y. <gn...@m1...> - 2002-04-04 09:03:30
|
Now is the time to sync up to mainline. Paul, please note that the change of shwdt.c is from the mainline. 2002-04-04 NIIBE Yutaka <gn...@m1...> Update to 2.5.8-pre1. * AGAINST-2.5.8-pre1: New file. * AGAINST-2.5.7: Removed. * Makefile: Version 2.5.8-pre1. * Makefile, arch/sh/kernel/sh_ksyms.c, drivers/block/rd.c, drivers/char/shwdt.c, drivers/net/Config.in, drivers/pci/pci.ids, init/do_mounts.c: Include changes from mainline (2.5.8-pre1). * arch/sh/kernel/sh_ksyms.c (simple_strtol, strtok): Removed. * drivers/char/shwdt.c (nowayout): New module option (to be configured at runtime by Matt Domsch). Index: Makefile =================================================================== RCS file: /cvsroot/linuxsh/linux/Makefile,v retrieving revision 1.12 diff -u -3 -p -r1.12 Makefile --- Makefile 22 Mar 2002 10:52:09 -0000 1.12 +++ Makefile 4 Apr 2002 08:50:42 -0000 @@ -1,12 +1,12 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 7 -EXTRAVERSION = -sh +SUBLEVEL = 8 +EXTRAVERSION = -pre1-sh KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) -KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//") +KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g") CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ @@ -342,7 +342,7 @@ init/main.o: init/main.c include/config/ $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $< init/do_mounts.o: init/do_mounts.c include/config/MARKER - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $< + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $< fs lib mm ipc kernel drivers net sound: dummy $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@) Index: arch/sh/kernel/sh_ksyms.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/sh_ksyms.c,v retrieving revision 1.2 diff -u -3 -p -r1.2 sh_ksyms.c --- arch/sh/kernel/sh_ksyms.c 26 Mar 2002 01:56:39 -0000 1.2 +++ arch/sh/kernel/sh_ksyms.c 4 Apr 2002 08:50:42 -0000 @@ -36,9 +36,6 @@ EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(no_irq_type); -EXPORT_SYMBOL(simple_strtol); - -EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strlen); Index: drivers/block/rd.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/block/rd.c,v retrieving revision 1.5 diff -u -3 -p -r1.5 rd.c --- drivers/block/rd.c 22 Mar 2002 04:44:45 -0000 1.5 +++ drivers/block/rd.c 4 Apr 2002 08:50:42 -0000 @@ -405,9 +405,10 @@ static void __exit rd_cleanup (void) for (i = 0 ; i < NUM_RAMDISKS; i++) { struct block_device *bdev = rd_bdev[i]; rd_bdev[i] = NULL; - if (bdev) + if (bdev) { + invalidate_bdev(bdev, 1); blkdev_put(bdev, BDEV_FILE); - destroy_buffers(mk_kdev(MAJOR_NR, i)); + } } devfs_unregister (devfs_handle); Index: drivers/char/shwdt.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/char/shwdt.c,v retrieving revision 1.4 diff -u -3 -p -r1.4 shwdt.c --- drivers/char/shwdt.c 15 Jan 2002 07:59:52 -0000 1.4 +++ drivers/char/shwdt.c 4 Apr 2002 08:50:42 -0000 @@ -9,6 +9,9 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. + * + * 14-Dec-2001 Matt Domsch <Mat...@de...> + * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT */ #include <linux/config.h> #include <linux/module.h> @@ -88,6 +91,15 @@ static struct watchdog_info sh_wdt_info; static struct timer_list timer; static unsigned long next_heartbeat; +#ifdef CONFIG_WATCHDOG_NOWAYOUT +static int nowayout = 1; +#else +static int nowayout = 0; +#endif + +MODULE_PARM(nowayout,"i"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); + /** * sh_wdt_write_cnt - Write to Counter * @@ -175,6 +187,10 @@ static int sh_wdt_open(struct inode *ino if (test_and_set_bit(0, &sh_is_open)) return -EBUSY; + if (nowayout) { + MOD_INC_USE_COUNT; + } + sh_wdt_start(); break; @@ -196,9 +212,9 @@ static int sh_wdt_open(struct inode *ino static int sh_wdt_close(struct inode *inode, struct file *file) { if (minor(inode->i_rdev) == WATCHDOG_MINOR) { -#ifndef CONFIG_WATCHDOG_NOWAYOUT - sh_wdt_stop(); -#endif + if (!nowayout) { + sh_wdt_stop(); + } clear_bit(0, &sh_is_open); } Index: drivers/net/Config.in =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/net/Config.in,v retrieving revision 1.6 diff -u -3 -p -r1.6 Config.in --- drivers/net/Config.in 22 Mar 2002 04:44:46 -0000 1.6 +++ drivers/net/Config.in 4 Apr 2002 08:50:42 -0000 @@ -57,6 +57,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; the if [ "$CONFIG_MIPS_AU1000" = "y" ]; then bool ' MIPS AU1000 Ethernet support' CONFIG_MIPS_AU1000_ENET fi + if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then + tristate ' SB1250 Ethernet support' CONFIG_NET_SB1250_MAC + fi if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi Index: drivers/pci/pci.ids =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/pci/pci.ids,v retrieving revision 1.5 diff -u -3 -p -r1.5 pci.ids --- drivers/pci/pci.ids 22 Mar 2002 10:52:09 -0000 1.5 +++ drivers/pci/pci.ids 4 Apr 2002 08:50:42 -0000 @@ -824,6 +824,8 @@ 0074 56k Voice Modem 1033 8014 RCV56ACF 56k Voice Modem 009b Vrc5476 + 00a6 VRC5477 AC97 + 00e0 USB 2.0 1034 Framatome Connectors USA Inc. 1035 Comp. & Comm. Research Lab 1036 Future Domain Corp. @@ -1108,12 +1110,14 @@ 1059 Teknor Industrial Computers Inc 105a Promise Technology, Inc. 0d30 20265 + 1275 20275 4d30 20267 4d33 20246 4d38 20262 4d68 20268 6268 20268R 4d69 20269 + 5275 20276 5300 DC5300 105b Foxconn International, Inc. 105c Wipro Infotech Limited @@ -1192,11 +1196,21 @@ 0017 Paddington Mac I/O 0018 UniNorth FireWire 0019 KeyLargo USB - 001e UniNorth PCI + 001e UniNorth Internal PCI 001f UniNorth PCI 0020 UniNorth AGP - 0021 UniNorth GMAC + 0021 UniNorth GMAC (Sun GEM) 0022 KeyLargo Mac I/O + 0024 UniNorth/Pangea GMAC (Sun GEM) + 0025 KeyLargo/Pangea Mac I/O + 0026 KeyLargo/Pangea USB + 0027 UniNorth/Pangea AGP + 0028 UniNorth/Pangea PCI + 0029 UniNorth/Pangea Internal PCI + 002d UniNorth 1.5 AGP + 002e UniNorth 1.5 PCI + 002f UniNorth 1.5 Internal PCI + 0030 UniNorth/Pangea FireWire 106c Hyundai Electronics America 8801 Dual Pentium ISA/PCI Motherboard 8802 PowerPC ISA/PCI Motherboard @@ -2620,6 +2634,8 @@ 0005 ATP850UF 0006 ATP860 NO-BIOS 0007 ATP860 + 0008 ATP865 NO-ROM + 0009 ATP865 8002 AEC6710 SCSI-2 Host Adapter 8010 AEC6712UW SCSI 8020 AEC6712U SCSI @@ -3967,7 +3983,7 @@ 9511 16PCI954 Function 1 15ed 2000 Macrolink MCCR Serial p4-7 of 8 15ed 2001 Macrolink MCCR Serial p4-15 of 16 - 9521 Oxford Semi OX16PCI952 PCI/dual 16950 UART + 9521 16PCI952 PCI/dual 16950 UART 1416 Multiwave Innovation pte Ltd 1417 Convergenet Technologies Inc 1418 Kyushu electronics systems Inc Index: init/do_mounts.c =================================================================== RCS file: /cvsroot/linuxsh/linux/init/do_mounts.c,v retrieving revision 1.3 diff -u -3 -p -r1.3 do_mounts.c --- init/do_mounts.c 22 Mar 2002 04:44:46 -0000 1.3 +++ init/do_mounts.c 4 Apr 2002 08:50:42 -0000 @@ -827,7 +827,7 @@ void prepare_namespace(void) create_dev("/dev/root", ROOT_DEV, NULL); if (mount_initrd) { - if (initrd_load() && kdev_same(ROOT_DEV, mk_kdev(RAMDISK_MAJOR, 0))) { + if (initrd_load() && !kdev_same(ROOT_DEV, mk_kdev(RAMDISK_MAJOR, 0))) { handle_initrd(); goto out; } |
From: Stuart M. <stu...@st...> - 2002-04-03 18:18:41
|
Fabio If you look at the bit of code in assembler, it reads the value from the INTEVT register, shifts right by 5 and subtracts 16. So an interrupt code of 0xd corrisponds to INTEVT code of 0x3a0. Have a look at the interrupt code table in the appropriate manual, and you'll see which interrupt this corrisponds to. I don't have a 7709 manual to hand, but IIRC this is an external interrupt on all SuperH parts. So something on your board is raising an interrupt, and this error message is saying that there is no interrupt handler installed to handle it. This could just be a mis-configuration issue. The interrupt controllers on some of the SH3's have quite a few modes and config registers. When your board was designed, they probably intended the interrupt controller to be set up in a particular way, make sure you're doing this. Alternativly something on your board really is raising an interrupt. Hopefully your board has some external logic to control enabling and disabling of interrupts from peripherials, so maybe this needs to be set up before you enable interrupts at the CPU level. Or maybe the device which is raising the interrupt at boot time needs to be initialised first. Either would be pretty grotty, most devices power up with interrupts disabled and/or inactive until you do something to provoke them, but it wouldn't be the first time somebody had designed hardware that didn't work that way. If all else fails, you could look at using the irq_imask routines to disable the interrupt using the IMASK in the status register, but that should be a last resort, as it results in all interrupts of lower priority being disabled, so could disbale something you need. Hope this helps Stuart On Wed, 3 Apr 2002 16:12:28 +0200 fg...@ti... wrote: > Sorry, > but I don't understand what means: > "unexpected IRQ trap at vector 0d" > > I suppose it is an interrupt always entering but I don't understand what is > its source. > > Thanks. > > Fabio > > On Tuesday 02 April 2002 14:27, Stuart Menefy wrote: > > Hi Fabio > > > > You might like to have a look at the 'board porting guide' a colleague > > here wrote. Have a look at: > > http://www.linuxsh.st.com/getting_started/board_porting.php3 > > > > As far as I know, you'll be the first person to try it in anger, so any > > comments welcome! > > > > You're right, it sounds like you have a pending interrupt. So the first > > thing I'd do is stick a printk at the start of do_IRQ(), and print the irq > > number (just after the little bit of asm code which retreives it). > > > > Stuart > > > > > > On Fri, 29 Mar 2002 10:55:32 +0100 > > > > fg...@ti... wrote: > > > Hi, Stuart, > > > I' porting linux SH on my sh3 7709a based board. > > > I'm able to compile and run for my board sh-boot got from CVS repository, > > > I'm able to compile the kernel 2.4.18 and I can boot it using gdb. > > > > > > Making a debug using printk("...."); while(1); to understant I see that > > > kernel stops execution at init/main.c -> start_kernel -> sti(); > > > > > > I compiled my kernel as my board were a SolutionEngine, but my board > > > isn't a SolutionEngine. > > > > > > Having read the Documentation/sh/ document from the CVS kernel and > > > seeing you are the father of sh_mv model, I write to you for asking: > > > 1) Is it possible when I enable the interrupt mask with sti() an > > > interrupt pending occurs which I have no handler for? > > > > > > 2) There is an optiminezed way to trace this kind of troubles? > > > > > > > > > Thanks a lot. > > > > > > Fabio -- Stuart Menefy stu...@st... STMicroelectronics Ltd ST Intranet: mo.bri.st.com Bristol, UK Rest of the World: www.linuxsh.st.com |
From: Pete L. <pet...@st...> - 2002-04-03 15:21:54
|
Hi All, Hopefully a quick question. I'm compiling two files, one a C file and one a CPP file. There is a single function in both files, see below for the compilation flags and resulting assembly. It looks like the g++ compiler (3.0.3) ignores the -nofpu flag, is this the expected behavior of the g++ compiler? thanks for your time - pete void CFileUsingFloat(void) { union{float f; int i;}tmpFloat; tmpFloat.f = sqrt(4.0); } sh4-linux-gcc -O2 -fno-rtti -fno-exceptions -fno-gnu-linker -Wstrict-prototy pes -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -D__KERNEL__ -DLINUX -D_LINU X_COMP_ -D_PCI_DRIVER -ml -m4-nofpu -mno-implicit-fp -DCPU=sh4 -DMODULE -c - o fp_testc.o fp_testc.c 000000e0 <CFileUsingFloat>: e0: 03 d1 mov.l f0 <CFileUsingFloat+0x10>,r1 ! 0x0 e2: 04 d5 mov.l f4 <CFileUsingFloat+0x14>,r5 ! 0x40100000 e4: 22 4f sts.l pr,@-r15 e6: 0b 41 jsr @r1 e8: 00 e4 mov #0,r4 ea: 26 4f lds.l @r15+,pr ec: 0b 00 rts ee: 09 00 nop f0: 00 00 .word 0x0000 f2: 00 00 .word 0x0000 f4: 00 00 .word 0x0000 f6: 10 40 dt r0 f8: 09 00 nop fa: 09 00 nop fc: 09 00 nop fe: 09 00 nop void CPPFileUsingFloat(void) { union{float f; int i;}tmpFloat; tmpFloat.f = sqrt(4.0); } sh4-linux-g++ -O2 -fno-rtti -fno-exceptions -fno-gnu-linker -Wstrict-prototy pes -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -D_ _KERNEL__ -DLINUX -D_LINUX_COMP_ -D_PCI_DRIVER -ml -m4-nofpu -mno-implicit-f p -DCPU=sh4 -c -o fp_testcpp.o fp_testcpp.cpp 000001c0 <CPPFileUsingFloat>: 1c0: 04 d1 mov.l 1d4 <CPPFileUsingFloat+0x14>,r1 ! 0x0 1c2: 22 4f sts.l pr,@-r15 1c4: 04 c7 mova 1d8 <CPPFileUsingFloat+0x18>,r0 1c6: 09 f5 fmov @r0+,fr5 1c8: 0b 41 jsr @r1 1ca: 09 f4 fmov @r0+,fr4 1cc: 26 4f lds.l @r15+,pr 1ce: 0b 00 rts 1d0: 09 00 nop 1d2: 09 00 nop ... 1dc: 00 00 .word 0x0000 1de: 10 40 dt r0 |
From: Fabio G. <fg...@ti...> - 2002-04-03 14:13:15
|
Sorry, but I don't understand what means: "unexpected IRQ trap at vector 0d" I suppose it is an interrupt always entering but I don't understand what is its source. Thanks. Fabio On Tuesday 02 April 2002 14:27, Stuart Menefy wrote: > Hi Fabio > > You might like to have a look at the 'board porting guide' a colleague > here wrote. Have a look at: > http://www.linuxsh.st.com/getting_started/board_porting.php3 > > As far as I know, you'll be the first person to try it in anger, so any > comments welcome! > > You're right, it sounds like you have a pending interrupt. So the first > thing I'd do is stick a printk at the start of do_IRQ(), and print the irq > number (just after the little bit of asm code which retreives it). > > Stuart > > > On Fri, 29 Mar 2002 10:55:32 +0100 > > fg...@ti... wrote: > > Hi, Stuart, > > I' porting linux SH on my sh3 7709a based board. > > I'm able to compile and run for my board sh-boot got from CVS repository, > > I'm able to compile the kernel 2.4.18 and I can boot it using gdb. > > > > Making a debug using printk("...."); while(1); to understant I see that > > kernel stops execution at init/main.c -> start_kernel -> sti(); > > > > I compiled my kernel as my board were a SolutionEngine, but my board > > isn't a SolutionEngine. > > > > Having read the Documentation/sh/ document from the CVS kernel and > > seeing you are the father of sh_mv model, I write to you for asking: > > 1) Is it possible when I enable the interrupt mask with sti() an > > interrupt pending occurs which I have no handler for? > > > > 2) There is an optiminezed way to trace this kind of troubles? > > > > > > Thanks a lot. > > > > Fabio |
From: Thomas W. <tw...@2m...> - 2002-04-03 13:00:01
|
Thanks! This is reassuring - at least now I know - that it can be done (and yes PAL is what I'm going for) Now I "only" need to know how to achieve those modes. I can see that you are affiliated with tvia - I tried you web page earlier inorder to find a reference guide but didn't find any. Can you tell me where I can find such a thing? TIA Thomas Yuankang Lee wrote: > > Hi, > > The following list only includes TV modes. Maybe it is helpful for you. > > CyberPro5000 TV mode: > ------------------------------------------- > | Resolution| NTSC (60Hz) | PAL (50Hz) | > |-----------|--------------|--------------| > | 640x440 | Yes | N/A | > | 640x480 | Yes | Yes | > | 720x480 | Yes | Yes | > | 720x540 | N/A | Yes | > | 800x600 | N/A | Yes | > | 768x576 | N/A | Yes | > | 720x576 | N/A | Yes | > ------------------------------------------- > > Regards, > > Yuankang Li > > ----- Original Message ----- > From: "Thomas Wentzel" <tw...@2m...> > To: <lin...@li...> > Sent: Wednesday, April 03, 2002 6:57 PM > Subject: [Linux-fbdev-devel] vesa cyberpro5000 > > > Hi! > > > > I'm not sure this is the right list to ask, but I can't think of a > > better place. > > > > I've read that S3's implementation of VESA allows for setting almost > > any resolution (not just the "standard" resolution - as is the case > > for most VESA implementation). > > > > Well... Can anybody tell me whether the CyberPro 5000 chip has support > > for this as well. In particular I need to set the resolution to 768x576. > > > > If you can point me to some solid information on the chip - that will > > do just fine... > > > > Regards > > Thomas > > > > > > _______________________________________________ > > Linux-fbdev-devel mailing list > > Lin...@li... > > https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel |
From: Yuankang L. <yk...@hf...> - 2002-04-03 12:27:35
|
SGksDQoNClRoZSBmb2xsb3dpbmcgbGlzdCBvbmx5IGluY2x1ZGVzIFRWIG1vZGVzLiBNYXliZSBp dCBpcyBoZWxwZnVsIGZvciB5b3UuDQoNCkN5YmVyUHJvNTAwMCBUViBtb2RlOg0KLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KfCBSZXNvbHV0aW9ufCAgTlRTQyAo NjBIeikgfCAgUEFMICg1MEh6KSAgfA0KfC0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tfC0tLS0t LS0tLS0tLS0tfA0KfCAgNjQweDQ0MCAgfCAgICBZZXMgICAgICAgICAgfCAgICAgTi9BICAgICAg ICAgfA0KfCAgNjQweDQ4MCAgfCAgICBZZXMgICAgICAgICAgfCAgICAgWWVzICAgICAgICAgIHwN CnwgIDcyMHg0ODAgIHwgICAgWWVzICAgICAgICAgIHwgICAgIFllcyAgICAgICAgICB8DQp8ICA3 MjB4NTQwICB8ICAgIE4vQSAgICAgICAgIHwgICAgIFllcyAgICAgICAgICB8DQp8ICA4MDB4NjAw ICB8ICAgIE4vQSAgICAgICAgIHwgICAgIFllcyAgICAgICAgICB8DQp8ICA3Njh4NTc2ICB8ICAg IE4vQSAgICAgICAgIHwgICAgIFllcyAgICAgICAgICB8DQp8ICA3MjB4NTc2ICB8ICAgIE4vQSAg ICAgICAgIHwgICAgIFllcyAgICAgICAgICB8DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tDQoNClJlZ2FyZHMsDQoNCll1YW5rYW5nIExpDQoNCg0KLS0tLS0gT3Jp Z2luYWwgTWVzc2FnZSAtLS0tLSANCkZyb206ICJUaG9tYXMgV2VudHplbCIgPHR3QDJtLmRrPg0K VG86IDxsaW51eC1mYmRldi1kZXZlbEBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQ+DQpTZW50OiBXZWRu ZXNkYXksIEFwcmlsIDAzLCAyMDAyIDY6NTcgUE0NClN1YmplY3Q6IFtMaW51eC1mYmRldi1kZXZl bF0gdmVzYSBjeWJlcnBybzUwMDANCg0KDQo+IEhpIQ0KPiANCj4gSSdtIG5vdCBzdXJlIHRoaXMg aXMgdGhlIHJpZ2h0IGxpc3QgdG8gYXNrLCBidXQgSSBjYW4ndCB0aGluayBvZiBhDQo+IGJldHRl ciBwbGFjZS4NCj4gDQo+IEkndmUgcmVhZCB0aGF0IFMzJ3MgaW1wbGVtZW50YXRpb24gb2YgVkVT QSBhbGxvd3MgZm9yIHNldHRpbmcgYWxtb3N0DQo+IGFueSByZXNvbHV0aW9uIChub3QganVzdCB0 aGUgInN0YW5kYXJkIiByZXNvbHV0aW9uIC0gYXMgaXMgdGhlIGNhc2UNCj4gZm9yIG1vc3QgVkVT QSBpbXBsZW1lbnRhdGlvbikuDQo+IA0KPiBXZWxsLi4uIENhbiBhbnlib2R5IHRlbGwgbWUgd2hl dGhlciB0aGUgQ3liZXJQcm8gNTAwMCBjaGlwIGhhcyBzdXBwb3J0DQo+IGZvciB0aGlzIGFzIHdl bGwuIEluIHBhcnRpY3VsYXIgSSBuZWVkIHRvIHNldCB0aGUgcmVzb2x1dGlvbiB0byA3Njh4NTc2 Lg0KPiANCj4gSWYgeW91IGNhbiBwb2ludCBtZSB0byBzb21lIHNvbGlkIGluZm9ybWF0aW9uIG9u IHRoZSBjaGlwIC0gdGhhdCB3aWxsDQo+IGRvIGp1c3QgZmluZS4uLiANCj4gDQo+IFJlZ2FyZHMN Cj4gICBUaG9tYXMNCj4gDQo+IA0KPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fXw0KPiBMaW51eC1mYmRldi1kZXZlbCBtYWlsaW5nIGxpc3QNCj4gTGludXgt ZmJkZXYtZGV2ZWxAbGlzdHMuc291cmNlZm9yZ2UubmV0DQo+IGh0dHBzOi8vbGlzdHMuc291cmNl Zm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL2xpbnV4LWZiZGV2LWRldmVsDQo= |
From: NIIBE Y. <gn...@m1...> - 2002-04-03 02:24:14
|
David McKay wrote: > It is in chapter 4 of the hardware manual, section 4.5 > "Memory-mapped Cache Configuration". It says "the OC content can be read > and > written by a P1 and P2 area program ......". Thank you. I've now understood. OC can be handled at P1. IC should be handled at P2. So, here is the change for 2.4 (not applying 2002-04-01 change). I'll commit this soon. 2002-04-03 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache-sh4.c (flush_cache_4096_all): New function. (flush_icache_all): New function. (flush_cache_4096): Changed the ifdef condition and I-cache handling. (flush_cache_all, flush_cache_range): New implementation using flush_icache_all and flush_cache_4096_all. * arch/sh/mm/clear_page.S (__flush_cache_4096_all): New function. Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.1.1.1.2.4 diff -u -3 -p -r1.1.1.1.2.4 cache-sh4.c --- arch/sh/mm/cache-sh4.c 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.4 +++ arch/sh/mm/cache-sh4.c 3 Apr 2002 02:21:06 -0000 @@ -207,10 +207,51 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } +static void flush_cache_4096_all(unsigned long start) +{ +#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr; + for (addr = start; addr < start + 4096; addr += 32) + ctrl_outl(0, addr); +#else + register unsigned long __r0 __asm__ ("r0") = 0; + register unsigned long __r1 __asm__ ("r1") = 128; + register unsigned long __r4 __asm__ ("r4"); + register unsigned long __r5 __asm__ ("r5"); + register unsigned long __r6 __asm__ ("r6"); + register unsigned long __r7 __asm__ ("r7"); + extern void __flush_cache_4096_all(unsigned long); + + asm volatile("jsr @%7; nop" + : "=&r" (__r4), "=&r" (__r5), "=&r" (__r6), "=&r" (__r7) + : "0" (start), "r" (__r0), "r" (__r1), + "r" (__flush_cache_4096_all + 0x20000000) + : "pr"); +#endif +} + static inline void flush_cache_4096(unsigned long start, unsigned long phys) { -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) + if (start >= CACHE_OC_ADDRESS_ARRAY) { + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr, data; + for (addr = start; addr < start + 4096; addr += 32) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } + } else +#endif + { register unsigned long addr __asm__ ("r4"); register unsigned long data __asm__ ("r0"); register unsigned long __r5 __asm__ ("r5") = phys; @@ -223,18 +264,7 @@ static inline void flush_cache_4096(unsi : "0" (start), "1" (__flush_cache_4096 + 0x20000000), "r" (__r5), "r" (__r6), "r" (__r7) : "pr"); -#else - /* - * SH7751 and ST40 have no restriction to handle cache. - * (While SH7750 must do that at P2 area.) - */ - unsigned long addr, data; - for (addr = start; addr < start + 4096; addr += 32) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); } -#endif } /* @@ -261,25 +291,55 @@ void flush_dcache_page(struct page *page } } -void flush_cache_all(void) +static inline void flush_icache_all(void) { - extern unsigned long empty_zero_page[1024]; unsigned long flags; - unsigned long addr; save_and_cli(flags); + jump_to_P2(); + /* Flush I-cache */ + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); + back_to_P1(); + restore_flags(flags); +} + +#undef C_IMPLEMENTATION_OF_CACHE_ALL + +void flush_cache_all(void) +{ + extern unsigned long empty_zero_page[1024]; /* Prefetch the data to write back D-cache */ + +#ifdef C_IMPLEMENTATION_OF_CACHE_ALL + unsigned long addr; + for (addr = (unsigned long)empty_zero_page; addr < (unsigned long)empty_zero_page + 1024*16; addr += L1_CACHE_BYTES) asm volatile("pref @%0"::"r" (addr)); - - jump_to_P2(); - /* Flush D-cache/I-cache */ - ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_P1(); - restore_flags(flags); +#else + unsigned long a0, a1, a2, a3, cnt; + asm volatile( + "mov %0, %1; add #32, %1\n\t" + "mov %0, %2; add #64, %2\n\t" + "mov %1, %3; add #64, %3\n\t" + "1:\n\t" + "pref @%0\n\t" + "dt %4\n\t" + "pref @%1\n\t" + "add %5, %0\n\t" + "pref @%2\n\t" + "add %5, %1\n\t" + "pref @%3\n\t" + "add %5, %2\n\t" + "bf/s 1b\n\t" + " add %5, %3" + : "=&r" (a0), "=&r" (a1), "=&r" (a2), "=&r" (a3), "=&r" (cnt) + : "r" (32*4), "0" (empty_zero_page), "4" (1024*16/32/4) + : "t"); +#endif + flush_icache_all(); } void flush_cache_mm(struct mm_struct *mm) @@ -341,15 +401,51 @@ static void __flush_cache_page(struct vm void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - /* - * We could call flush_cache_page for the pages of these - * range, but it's really time consuming (we have to scan the - * caches all the time...). - * - * We can't use A-bit magic, as there's the case we don't have - * valid entry on TLB. - */ - flush_cache_all(); + unsigned long p = start & PAGE_MASK; + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + unsigned long d = 0; + + dir = pgd_offset(mm, p); + pmd = pmd_offset(dir, p); + + do { + if (pmd_none(*pmd) || pmd_bad(*pmd)) { + p &= ~((1 << PMD_SHIFT) -1); + p += (1 << PMD_SHIFT); + pmd++; + continue; + } + pte = pte_offset(pmd, p); + do { + entry = *pte; + if ((pte_val(entry) & _PAGE_PRESENT)) { + phys = pte_val(entry)&PTE_PHYS_MASK; + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } + } + pte++; + p += PAGE_SIZE; + } while (p < end && (unsigned long)pte & PAGE_MASK); + pmd++; + } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY); + if (d & 2) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x1000); + if (d & 4) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x2000); + if (d & 8) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x3000); + flush_icache_all(); } /* Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 clear_page.S --- arch/sh/mm/clear_page.S 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.1 +++ arch/sh/mm/clear_page.S 3 Apr 2002 02:21:06 -0000 @@ -182,7 +182,6 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -#if defined(CONFIG_CPU_SUBTYPE_SH7750) ENTRY(__flush_cache_4096) .rept 128 mov.l @r4,r0 @@ -191,6 +190,34 @@ ENTRY(__flush_cache_4096) bf 1f mov.l r7,@r4 1: add #32,r4 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop + +#if defined(CONFIG_CPU_SUBTYPE_SH7750) +ENTRY(__flush_cache_4096_all) + mov r4,r5 + mov r4,r6 + mov r4,r7 + add #32,r5 + add #-64,r6 + add #-32,r7 + .rept 32 + mov.l r0,@r4 + add r1,r6 + mov.l r0,@r5 + add r1,r7 + mov.l r0,@r6 + add r1,r4 + mov.l r0,@r7 + add r1,r5 .endr nop nop Index: arch/sh/mm/copy_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/copy_page.S,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 copy_page.S --- arch/sh/mm/copy_page.S 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.1 +++ arch/sh/mm/copy_page.S 3 Apr 2002 02:21:06 -0000 @@ -84,7 +84,6 @@ ENTRY(copy_page) * r10 --- to * r11 --- from */ -#include <linux/linkage.h> ENTRY(__copy_user_page) mov.l r8,@-r15 mov.l r9,@-r15 -- |
From: David M. <dav...@st...> - 2002-04-02 14:23:18
|
gn...@m1... wrote: > > Thanks for the testing. Umm... I've read the hardware manual of SH7750 and > SH7751. I couldn't find the difference wrt the description of P2 requirement > of cache handling. I'll test this with SH7751 SolutionEngine. > Niibe-san, It is in chapter 4 of the hardware manual, section 4.5 "Memory-mapped Cache Configuration". It says "the OC content can be read and written by a P1 and P2 area program ......". > IIRC, Takashi Yoshii also has mentioned this. I'm not sure if it's > future plan or actual implementation, though. > I believe it is implementation. > David, I'd like to confirm. Is it OK for ST40STB1? Yup, the ST40 is based on the later core version, so it should be fine. -- Dave McKay Software Engineer STMicroelectronics Email: dav...@st... |
From: Pete L. <p_l...@ya...> - 2002-04-01 14:46:30
|
Hi all, I am compiling a kernel module that makes use of floating point, which I understand is not a good approach, but at the moment it's the best of a bad situation. This module is running on a 2.4.13-pre2 kernel on an ST40 (SH4) proc. GCC ver. 3.0.3. I have added a fair amount of "soft float" math routines to avoid the use of the floating point hardware, and I am compiling the module and kernel, using both the "-m4-nofpu" and "no-implicit-fp" flags. On assignment of a function returning a float type to a float type local variable, an "flds" is generated, and I end up in the kernel's do_fpu_state_restore() which is an error since I'm in kernel mode. Are there any other flags to make use of that will avoid the generation of floating point commands? I thought that "-m4-nofpu" was the same as "-m3", (SH4 with no FPU?), so it seems I have misunderstood something along the way. Thanks for your time. __________________________________________________ Do You Yahoo!? Yahoo! Greetings - send holiday greetings for Easter, Passover http://greetings.yahoo.com/ |
From: NIIBE Y. <gn...@m1...> - 2002-04-01 02:17:14
|
And here's the change for 2.4. 2002-04-01 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache-sh4.c (flush_cache_4096_all): New function. (flush_icache_all): New function. (flush_cache_4096): Changed the ifdef condition only for ST40STB1. (flush_cache_all, flush_cache_range): New implementation using flush_icache_all and flush_cache_4096_all. * arch/sh/mm/clear_page.S (__flush_cache_4096_all): New function. Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.1.1.1.2.4 diff -u -3 -p -r1.1.1.1.2.4 cache-sh4.c --- arch/sh/mm/cache-sh4.c 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.4 +++ arch/sh/mm/cache-sh4.c 1 Apr 2002 02:13:31 -0000 @@ -207,10 +207,48 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } +static void flush_cache_4096_all(unsigned long start) +{ +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * ST40 have no restriction to handle cache. + * (While SH7750/SH7751 must do that at P2 area.) + */ + unsigned long addr; + for (addr = start; addr < start + 4096; addr += 32) + ctrl_outl(0, addr); +#else + register unsigned long __r0 __asm__ ("r0") = 0; + register unsigned long __r1 __asm__ ("r1") = 128; + register unsigned long __r4 __asm__ ("r4"); + register unsigned long __r5 __asm__ ("r5"); + register unsigned long __r6 __asm__ ("r6"); + register unsigned long __r7 __asm__ ("r7"); + extern void __flush_cache_4096_all(unsigned long); + + asm volatile("jsr @%7; nop" + : "=&r" (__r4), "=&r" (__r5), "=&r" (__r6), "=&r" (__r7) + : "0" (start), "r" (__r0), "r" (__r1), + "r" (__flush_cache_4096_all + 0x20000000) + : "pr"); +#endif +} + static inline void flush_cache_4096(unsigned long start, unsigned long phys) { -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * ST40 have no restriction to handle cache. + * (While SH7750/SH7751 must do that at P2 area.) + */ + unsigned long addr, data; + for (addr = start; addr < start + 4096; addr += 32) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } +#else register unsigned long addr __asm__ ("r4"); register unsigned long data __asm__ ("r0"); register unsigned long __r5 __asm__ ("r5") = phys; @@ -223,17 +261,6 @@ static inline void flush_cache_4096(unsi : "0" (start), "1" (__flush_cache_4096 + 0x20000000), "r" (__r5), "r" (__r6), "r" (__r7) : "pr"); -#else - /* - * SH7751 and ST40 have no restriction to handle cache. - * (While SH7750 must do that at P2 area.) - */ - unsigned long addr, data; - for (addr = start; addr < start + 4096; addr += 32) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } #endif } @@ -261,25 +288,56 @@ void flush_dcache_page(struct page *page } } -void flush_cache_all(void) +static inline void flush_icache_all(void) { - extern unsigned long empty_zero_page[1024]; unsigned long flags; - unsigned long addr; save_and_cli(flags); + jump_to_P2(); + /* Flush I-cache */ + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); + back_to_P1(); + restore_flags(flags); +} + +#undef C_IMPLEMENTATION_OF_CACHE_ALL + +void flush_cache_all(void) +{ + extern unsigned long empty_zero_page[1024]; /* Prefetch the data to write back D-cache */ + +#ifdef C_IMPLEMENTATION_OF_CACHE_ALL + unsigned long addr; + for (addr = (unsigned long)empty_zero_page; addr < (unsigned long)empty_zero_page + 1024*16; addr += L1_CACHE_BYTES) asm volatile("pref @%0"::"r" (addr)); - - jump_to_P2(); - /* Flush D-cache/I-cache */ - ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_P1(); - restore_flags(flags); +#else + unsigned long a0, a1, a2, a3, cnt; + asm volatile( + "mov %0, %1; add #32, %1\n\t" + "mov %0, %2; add #64, %2\n\t" + "mov %1, %3; add #64, %3\n\t" + "1:\n\t" + "pref @%0\n\t" + "dt %4\n\t" + "pref @%1\n\t" + "add %5, %0\n\t" + "pref @%2\n\t" + "add %5, %1\n\t" + "pref @%3\n\t" + "add %5, %2\n\t" + "bf/s 1b\n\t" + " add %5, %3" + : "=&r" (a0), "=&r" (a1), "=&r" (a2), "=&r" (a3), "=&r" (cnt) + : "r" (32*4), "0" (empty_zero_page), "4" (1024*16/32/4) + : "t"); + } +#endif + flush_icache_all(); } void flush_cache_mm(struct mm_struct *mm) @@ -341,15 +399,51 @@ static void __flush_cache_page(struct vm void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - /* - * We could call flush_cache_page for the pages of these - * range, but it's really time consuming (we have to scan the - * caches all the time...). - * - * We can't use A-bit magic, as there's the case we don't have - * valid entry on TLB. - */ - flush_cache_all(); + unsigned long p = start & PAGE_MASK; + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + unsigned long d = 0; + + dir = pgd_offset(mm, p); + pmd = pmd_offset(dir, p); + + do { + if (pmd_none(*pmd) || pmd_bad(*pmd)) { + p &= ~((1 << PMD_SHIFT) -1); + p += (1 << PMD_SHIFT); + pmd++; + continue; + } + pte = pte_offset(pmd, p); + do { + entry = *pte; + if ((pte_val(entry) & _PAGE_PRESENT)) { + phys = pte_val(entry)&PTE_PHYS_MASK; + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } + } + pte++; + p += PAGE_SIZE; + } while (p < end && (unsigned long)pte & PAGE_MASK); + pmd++; + } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY); + if (d & 2) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x1000); + if (d & 4) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x2000); + if (d & 8) + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x3000); + flush_icache_all(); } /* Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 clear_page.S --- arch/sh/mm/clear_page.S 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.1 +++ arch/sh/mm/clear_page.S 1 Apr 2002 02:13:31 -0000 @@ -182,7 +182,7 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if !defined(CONFIG_CPU_SUBTYPE_ST40STB1) /* SH7750 or SH7751 */ ENTRY(__flush_cache_4096) .rept 128 mov.l @r4,r0 @@ -191,6 +191,33 @@ ENTRY(__flush_cache_4096) bf 1f mov.l r7,@r4 1: add #32,r4 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop + +ENTRY(__flush_cache_4096_all) + mov r4,r5 + mov r4,r6 + mov r4,r7 + add #32,r5 + add #-64,r6 + add #-32,r7 + .rept 32 + mov.l r0,@r4 + add r1,r6 + mov.l r0,@r5 + add r1,r7 + mov.l r0,@r6 + add r1,r4 + mov.l r0,@r7 + add r1,r5 .endr nop nop Index: arch/sh/mm/copy_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/copy_page.S,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 copy_page.S --- arch/sh/mm/copy_page.S 29 Mar 2002 00:01:08 -0000 1.1.1.1.2.1 +++ arch/sh/mm/copy_page.S 1 Apr 2002 02:13:31 -0000 @@ -84,7 +84,6 @@ ENTRY(copy_page) * r10 --- to * r11 --- from */ -#include <linux/linkage.h> ENTRY(__copy_user_page) mov.l r8,@-r15 mov.l r9,@-r15 |
From: NIIBE Y. <gn...@m1...> - 2002-04-01 01:58:18
|
Here's the change. 2002-04-01 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache-sh4.c (flush_cache_4096_all, flush_cache_4096): Changed the compile time condition for ST40. SH7751 needs to be P2 when handling cache. * arch/sh/mm/clear_page.S (__flush_cache_4096_all): Renamed from __flush_cache_4096_nocheck. Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.10 diff -u -3 -p -r1.10 cache-sh4.c --- arch/sh/mm/cache-sh4.c 1 Apr 2002 01:29:43 -0000 1.10 +++ arch/sh/mm/cache-sh4.c 1 Apr 2002 01:55:09 -0000 @@ -208,37 +208,48 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } -static void flush_cache_4096_nocheck(unsigned long start) +static void flush_cache_4096_all(unsigned long start) { -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * ST40 have no restriction to handle cache. + * (While SH7750/SH7751 must do that at P2 area.) + */ + unsigned long addr; + for (addr = start; addr < start + 4096; addr += 32) + ctrl_outl(0, addr); +#else register unsigned long __r0 __asm__ ("r0") = 0; register unsigned long __r1 __asm__ ("r1") = 128; register unsigned long __r4 __asm__ ("r4"); register unsigned long __r5 __asm__ ("r5"); register unsigned long __r6 __asm__ ("r6"); register unsigned long __r7 __asm__ ("r7"); - extern void __flush_cache_4096_nocheck(unsigned long); + extern void __flush_cache_4096_all(unsigned long); asm volatile("jsr @%7; nop" : "=&r" (__r4), "=&r" (__r5), "=&r" (__r6), "=&r" (__r7) : "0" (start), "r" (__r0), "r" (__r1), - "r" (__flush_cache_4096_nocheck + 0x20000000) + "r" (__flush_cache_4096_all + 0x20000000) : "pr"); -#else - /* - * SH7751 and ST40 have no restriction to handle cache. - * (While SH7750 must do that at P2 area.) - */ - unsigned long addr; - for (addr = start; addr < start + 4096; addr += 32) - ctrl_outl(0, addr); #endif } static inline void flush_cache_4096(unsigned long start, unsigned long phys) { -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) + /* + * ST40 have no restriction to handle cache. + * (While SH7750/SH7751 must do that at P2 area.) + */ + unsigned long addr, data; + for (addr = start; addr < start + 4096; addr += 32) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } +#else register unsigned long addr __asm__ ("r4"); register unsigned long data __asm__ ("r0"); register unsigned long __r5 __asm__ ("r5") = phys; @@ -251,17 +262,6 @@ static inline void flush_cache_4096(unsi : "0" (start), "1" (__flush_cache_4096 + 0x20000000), "r" (__r5), "r" (__r6), "r" (__r7) : "pr"); -#else - /* - * SH7751 and ST40 have no restriction to handle cache. - * (While SH7750 must do that at P2 area.) - */ - unsigned long addr, data; - for (addr = start; addr < start + 4096; addr += 32) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } #endif } @@ -301,13 +301,15 @@ static inline void flush_icache_all(void restore_flags(flags); } +#undef C_IMPLEMENTATION_OF_CACHE_ALL + void flush_cache_all(void) { extern unsigned long empty_zero_page[1024]; /* Prefetch the data to write back D-cache */ -#if C_IMPLEMENTATION +#ifdef C_IMPLEMENTATION_OF_CACHE_ALL unsigned long addr; for (addr = (unsigned long)empty_zero_page; @@ -435,13 +437,13 @@ void flush_cache_range(struct vm_area_st } while (p < end); loop_exit: if (d & 1) - flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY); + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY); if (d & 2) - flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x1000); + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x1000); if (d & 4) - flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x2000); + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x2000); if (d & 8) - flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x3000); + flush_cache_4096_all(CACHE_OC_ADDRESS_ARRAY | 0x3000); if (vma->vm_flags & VM_EXEC) flush_icache_all(); } Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.4 diff -u -3 -p -r1.4 clear_page.S --- arch/sh/mm/clear_page.S 1 Apr 2002 01:29:43 -0000 1.4 +++ arch/sh/mm/clear_page.S 1 Apr 2002 01:55:09 -0000 @@ -182,7 +182,7 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -#if defined(CONFIG_CPU_SUBTYPE_SH7750) +#if !defined(CONFIG_CPU_SUBTYPE_ST40STB1) /* SH7750 or SH7751 */ ENTRY(__flush_cache_4096) .rept 128 mov.l @r4,r0 @@ -202,7 +202,7 @@ ENTRY(__flush_cache_4096) rts nop -ENTRY(__flush_cache_4096_nocheck) +ENTRY(__flush_cache_4096_all) mov r4,r5 mov r4,r6 mov r4,r7 Index: arch/sh/mm/copy_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/copy_page.S,v retrieving revision 1.2 diff -u -3 -p -r1.2 copy_page.S --- arch/sh/mm/copy_page.S 27 Mar 2002 09:30:48 -0000 1.2 +++ arch/sh/mm/copy_page.S 1 Apr 2002 01:55:09 -0000 @@ -84,7 +84,6 @@ ENTRY(copy_page) * r10 --- to * r11 --- from */ -#include <linux/linkage.h> ENTRY(__copy_user_page) mov.l r8,@-r15 mov.l r9,@-r15 |
From: NIIBE Y. <gn...@m1...> - 2002-04-01 00:59:37
|
Dustin McIntire wrote: > I've just tried Niibe-san's backport of the cache changes for the 2.4 > kernel. I'm running on a SH7751 based system, and I've run into some > trouble. It seems I get a kernel oops (Segmentaton fault) in > __flush_cache_page when using the /bin/ps binary. The oops goes away if I > simply force the CONFIG_CPU_SUBTYPE_SH7750 defines to true and use the 7750 > cache method. I'm still working to getting a better idea what is causing > the oops. Thanks for the testing. Umm... I've read the hardware manual of SH7750 and SH7751. I couldn't find the difference wrt the description of P2 requirement of cache handling. I'll test this with SH7751 SolutionEngine. IIRC, Takashi Yoshii also has mentioned this. I'm not sure if it's future plan or actual implementation, though. David, I'd like to confirm. Is it OK for ST40STB1? -- |
From: <dou...@th...> - 2002-03-30 12:17:56
|
<html> <head> <title>The Network Administrator</title> </head> <body topmargin="3" leftmargin="3"> <table border="1" width="79%"> <tr> <td width="100%" align="center"> <table cellpadding="0" cellspacing="0" border="0" width="555" height="81" style="border-style: none; border-width: 0px; margin-left: 0px"> <tr> <td align="center" width="128" height="36" rowspan="3" background="http://www.thenetworkadministrator.com/face1.gif"> <p align="left"> </p> </td> <td align="center" width="423" rowspan="3"><p align="center"><strong><font color="#000080"><big><big><big>The Network Administrator</big></big></big></font></strong></td> </tr> </table> <table border="0" width="98%" cellspacing="0" cellpadding="0" height="1"> <tr> <td width="100%" bgcolor="#000080" height="1"> <p align="left"><font color="#ffffff"><strong> &nb sp; A Website Dedicated to Computer Professionals</strong></font></td> </tr> <tr> <td width="100%" bgcolor="#FFFFFF" height="1"> <p align="right"><font color="#000080"><b> and those not so professional </b></font></td> </tr> </table> <table border="0" width="98%" cellspacing="0" cellpadding="3"> <tr> <td width="100%"> <hr noshade size="1"> </td> </tr> </table> <table border="0" width="99%" cellpadding="0" height="100%" cellspacing="0"> <tr> <td width="77%" align="left" valign="top"><!--end header--> <u><strong>Feature Articles:</strong></u><span class="regtextthin1"><font color="#0000FF" size="4"><br> </font></span><font color="#0000ff" size="4">How many certifications before you are a MCTT? (Microsoft Certified Test Taker)</font> <p align="left"><font face="Times New Roman" size="3"><img align="left" border="0" src="http://www.thenetworkadministrator.com/monkeypics/professional_mw.gif" width="80" height="120">Where is the line between having too many certifications and just enough? Does your resume give the impression that you have more experience in test taking than actual work experience? If this sounds like you then here's a quick test to see how you rank. Relax Poindexter...there's no test here. I was just kidding. <b>By Doug Chick</b><br> <a href="http://www.thenetworkadministrator.com"><font color="#0000ff"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></font></a></font></p> <font color="#0000FF"> <hr noshade size="1" align="left"> </font> <p><span class="regtextthin1"><font color="#0000FF" size="4"> <font color="#0000ff" face="Times New Roman" size="4">Are you choosing software for your company by what will look best on your resume? <br> <img align="left" border="0" height="84" src="http://209.26.235.107/monkeypics/boy_coloring_sm_wht.gif" width="84"><br> </font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3"> </font></span></font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3" color="#000000">First thing I do when looking for software for my company is research all available software similar to our needs. Then I do a detailed comparative analysis, followed by a call to a list of satisfied customers supplied by the software company. After all, isnt that what all Network Administrators do? Well, maybe not all...<br> <b>By Doug Chick</b><br> </font></span></span><font color="#0000FF"><a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a> </p> <hr noshade size="1" align="left"> <p align="left"><span class="regtextthin1"><font color="#0000FF" size="4"> Why wouldnt Microsoft package its own computer like Apple?</font></span><span style="font-size:10.0pt;font-family:Arial" class="regtextthin1"><br> </span><img border="0" src="http://209.26.235.107/pics/mbox.gif" align="left" width="122" height="113"></font>I Read an article by <span style="font-size:10.0pt;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family: "Times New Roman";mso-bidi-font-family:"Times New Roman"" class="regtextthin1">Phillip Smith</span><span style="font-size:10.0pt;font-family:Arial" class="regtextthin1"> that raised an interesting question; Why wouldnt Microsoft package its own computer like Apple or Sun, and stop selling its software to computer makers altogether? Microsoft could agree that they created a market that made them a monopoly and to add balance to the industry they would stop selling their product to computer makers and only use it in their own systems. <font color="#0000FF"> <br> </font> </span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF" size="4"><b>Has Monitoring your Network Given you a God Complex? <br> </b></font><img border="0" src="http://209.26.235.107/god.jpg" align="left" width="86" height="108">From your desk you can see who and when someone logs in, who and what e-mail they send and what websites that they frequently attend. Knowing this information can sometimes place you in difficult situations. You often ask yourself if you should interfere to help someone that you like, or don't like. See an e-mail that you know is damaging and wonder if you should stop or remove it completely. It's a very difficult position to be in and almost no one, short of other computer people know about it. So what do you do? I am now of the philosophy that, "Unless someone is in danger of being hurt--Stay out of it!" <br> <b>By Doug Chick</b><br> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF"><font face="Times New Roman" color="#0000FF" size="4">How many computer catalogs do companies think you need? </font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3"><br> <img border="0" src="http://209.26.235.107/pics/jerboa_stomp_sm_wht.gif" align="left" width="65" height="60"></font></span></font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3" color="#000000">On an average, I receive 5 computer accessories catalogs by mail, everyday. Thats 25 a week, 100 a month and 1200 an year. Now stacking 10 magazines on top of each other will give you an inch, and 1200 magazines will produce a stack 10 feet high. Lets review: 5 magazines X 5 days<span style="mso-spacerun: yes"> </span>= 25 X 4 weeks = 100 X 12 months = 1200 magazines = a stack 10 feet high.<br> </font></span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <hr noshade size="1" align="left"> <p align="left"><font size="4">Who wants to be a Network Administrator?<br> </font> <span style="font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family: "Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:EN-US; mso-bidi-language:AR-SA"><img border="0" src="http://209.26.235.107/pics/analyzing_t_v_head_mw.gif" align="left" width="66" height="99">Why are there so many people out there that are studying so hard to take your job away from you? Money. I was sitting in the movie theater with my wife last night and one of the ads on the screen before the movie started read: Be a Network Administrator and earn 87K a year. Well, two thumbs up again for those lying salary surveys. I dont really think that those salary surveys are lying as much as I believe that theres one network administrator out there that makes 47 millions dollars a year and is totally warping the salary curve.<br> </span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF" size="4">Is your career dependant on the operating system that you support?<br> <img border="0" src="http://209.26.235.107/pics/plunger_mw.gif" align="left" width="120" height="104"></font><br> <!--page-->If suddenly one day, the president of your company announced that he just struck a deal to change all the servers operating systems in your company to Serversoft (trademark pending) what would you do exactly? Furthermore, what if your company started hiring people that were Serversoft certified, (trademark pending) that had no real life computer experience and were paid more than you? How likely is that to happen? Ask a Novell Administrator.<span class="regtext"><font color="#0000FF"><br> </font></span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <p align="center"><a href="mailto:su...@th...">Submit an Article</a> </p> <p align="center"><a href="mailto:rem...@th..."><br> <font size="3"><b>Note, If you did not subscript to the Newsletter and wish to be removed, Click here!</b></font></a> </p> </td> <td width="25%" align="left" bordercolor="#000080"> <table border="1" width="100%" cellspacing="0" cellpadding="0" bordercolor="#FFFFFF" bgcolor="#000080" height="153"> <tr> <td width="100%" bordercolor="#FFFFFF" height="19"> <p align="center"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font size="2" color="#FFFFFF">Monkey Sling</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="30"> <p align="center"><font size="2" color="#FFFFFF">The Network Admins Survival Guide</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="30"> <p align="center"><font size="2" color="#FFFFFF">The Language of the End-User</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font size="2" color="#FFFFFF">Hacker Facts</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><small><font color="#FFFFFF">Conspiracy Theory</font></small></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><small><font color="#FFFFFF">Who Let the Bugs Out</font></small></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="8" align="center" bgcolor="#FFFFFF"> <p> </p> <p> </p> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="7" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> </table> <table border="0" width="100%" cellspacing="0" cellpadding="0" height="100%"> <tr> <td width="100%" height="346"></td> </tr> </table> <p> </td> </tr> </table> <table border="0" width="100%" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <p align="left"><strong>|</strong><font color="#0000FF"> Copyright 2001 TheNetworkAdministrator.com & DougChick.com |</font></td> </tr> </table> </td> </tr> </table> </body> </html> |
From: <dou...@th...> - 2002-03-30 01:49:04
|
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> <title>The Network Administrator</title> </head> <body topmargin="3" leftmargin="3"> <table border="1" width="79%"> <tr> <td width="100%" align="center"> <table cellpadding="0" cellspacing="0" border="0" width="555" height="81" style="border-style: none; border-width: 0px; margin-left: 0px"> <tr> <td align="center" width="128" height="36" rowspan="3" background="http://www.thenetworkadministrator.com/face1.gif"> <p align="left"> </p> </td> <td align="center" width="423" rowspan="3"><p align="center"><strong><font color="#000080"><big><big><big>The Network Administrator</big></big></big></font></strong></td> </tr> </table> <table border="0" width="98%" cellspacing="0" cellpadding="0" height="1"> <tr> <td width="100%" bgcolor="#000080" height="1"> <p align="left"><font color="#ffffff"><strong> &nb sp; A Website Dedicated to Computer Professionals</strong></font></td> </tr> <tr> <td width="100%" bgcolor="#FFFFFF" height="1"> <p align="right"><font color="#000080"><b> and those not so professional </b></font></td> </tr> </table> <table border="0" width="98%" cellspacing="0" cellpadding="3"> <tr> <td width="100%"> <hr noshade size="1"> </td> </tr> </table> <table border="0" width="99%" cellpadding="0" height="100%" cellspacing="0"> <tr> <td width="77%" align="left" valign="top"><!--end header--> <u><strong>Feature Articles:</strong></u><span class="regtextthin1"><font color="#0000FF" size="4"><br> </font></span><font color="#0000ff" size="4">How many certifications before you are a MCTT? (Microsoft Certified Test Taker)</font> <p align="left"><font face="Times New Roman" size="3"><img align="left" border="0" src="http://www.thenetworkadministrator.com/monkeypics/professional_mw.gif" width="80" height="120">Where is the line between having too many certifications and just enough? Does your resume give the impression that you have more experience in test taking than actual work experience? If this sounds like you then here's a quick test to see how you rank. Relax Poindexter...there's no test here. I was just kidding. <b>By Doug Chick</b><br> <a href="http://www.thenetworkadministrator.com"><font color="#0000ff"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></font></a></font></p> <font color="#0000FF"> <hr noshade size="1" align="left"> </font> <p><span class="regtextthin1"><font color="#0000FF" size="4"> <font color="#0000ff" face="Times New Roman" size="4">Are you choosing software for your company by what will look best on your resume? <br> <img align="left" border="0" height="84" src="http://209.26.235.107/monkeypics/boy_coloring_sm_wht.gif" width="84"><br> </font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3"> </font></span></font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3" color="#000000">First thing I do when looking for software for my company is research all available software similar to our needs. Then I do a detailed comparative analysis, followed by a call to a list of satisfied customers supplied by the software company. After all, isnt that what all Network Administrators do? Well, maybe not all...<br> <b>By Doug Chick</b><br> </font></span></span><font color="#0000FF"><a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a> </p> <hr noshade size="1" align="left"> <p align="left"><span class="regtextthin1"><font color="#0000FF" size="4"> Why wouldnt Microsoft package its own computer like Apple?</font></span><span style="font-size:10.0pt;font-family:Arial" class="regtextthin1"><br> </span><img border="0" src="http://209.26.235.107/pics/mbox.gif" align="left" width="122" height="113"></font>I Read an article by <span style="font-size:10.0pt;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family: "Times New Roman";mso-bidi-font-family:"Times New Roman"" class="regtextthin1">Phillip Smith</span><span style="font-size:10.0pt;font-family:Arial" class="regtextthin1"> that raised an interesting question; Why wouldnt Microsoft package its own computer like Apple or Sun, and stop selling its software to computer makers altogether? Microsoft could agree that they created a market that made them a monopoly and to add balance to the industry they would stop selling their product to computer makers and only use it in their own systems. <font color="#0000FF"> <br> </font> </span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF" size="4"><b>Has Monitoring your Network Given you a God Complex? <br> </b></font><img border="0" src="http://209.26.235.107/god.jpg" align="left" width="86" height="108">From your desk you can see who and when someone logs in, who and what e-mail they send and what websites that they frequently attend. Knowing this information can sometimes place you in difficult situations. You often ask yourself if you should interfere to help someone that you like, or don't like. See an e-mail that you know is damaging and wonder if you should stop or remove it completely. It's a very difficult position to be in and almost no one, short of other computer people know about it. So what do you do? I am now of the philosophy that, "Unless someone is in danger of being hurt--Stay out of it!" <br> <b>By Doug Chick</b><br> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF"><font face="Times New Roman" color="#0000FF" size="4">How many computer catalogs do companies think you need? </font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3"><br> <img border="0" src="http://209.26.235.107/pics/jerboa_stomp_sm_wht.gif" align="left" width="65" height="60"></font></span></font><span style="FONT-SIZE: 12pt"><font face="Times New Roman" size="3" color="#000000">On an average, I receive 5 computer accessories catalogs by mail, everyday. Thats 25 a week, 100 a month and 1200 an year. Now stacking 10 magazines on top of each other will give you an inch, and 1200 magazines will produce a stack 10 feet high. Lets review: 5 magazines X 5 days<span style="mso-spacerun: yes"> </span>= 25 X 4 weeks = 100 X 12 months = 1200 magazines = a stack 10 feet high.<br> </font></span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <hr noshade size="1" align="left"> <p align="left"><font size="4">Who wants to be a Network Administrator?<br> </font> <span style="font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family: "Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:EN-US; mso-bidi-language:AR-SA"><img border="0" src="http://209.26.235.107/pics/analyzing_t_v_head_mw.gif" align="left" width="66" height="99">Why are there so many people out there that are studying so hard to take your job away from you? Money. I was sitting in the movie theater with my wife last night and one of the ads on the screen before the movie started read: Be a Network Administrator and earn 87K a year. Well, two thumbs up again for those lying salary surveys. I dont really think that those salary surveys are lying as much as I believe that theres one network administrator out there that makes 47 millions dollars a year and is totally warping the salary curve.<br> </span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <hr noshade size="1" align="left"> <p align="left"><font color="#0000FF" size="4">Is your career dependant on the operating system that you support?<br> <img border="0" src="http://209.26.235.107/pics/plunger_mw.gif" align="left" width="120" height="104"></font><br> <!--page-->If suddenly one day, the president of your company announced that he just struck a deal to change all the servers operating systems in your company to Serversoft (trademark pending) what would you do exactly? Furthermore, what if your company started hiring people that were Serversoft certified, (trademark pending) that had no real life computer experience and were paid more than you? How likely is that to happen? Ask a Novell Administrator.<span class="regtext"><font color="#0000FF"><br> </font></span> <font color="#0000FF"> <a href="http://www.thenetworkadministrator.com"><img border="0" src="http://www.thenetworkadministrator.com/fullstory.jpg" width="70" height="20"></a></font> </p> <p align="center"><a href="mailto:su...@th...">Submit an Article<br> <br> <font size="4"><a href="mailto:rem...@th...">Please remove me from your newsletter.</font></a> </p> </td> <td width="25%" align="left" bordercolor="#000080"> <table border="1" width="100%" cellspacing="0" cellpadding="0" bordercolor="#FFFFFF" bgcolor="#000080" height="153"> <tr> <td width="100%" bordercolor="#FFFFFF" height="19"> <p align="center"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font size="2" color="#FFFFFF">Monkey Sling</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="30"> <p align="center"><font size="2" color="#FFFFFF">The Network Admins Survival Guide</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="30"> <p align="center"><font size="2" color="#FFFFFF">The Language of the End-User</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font size="2" color="#FFFFFF">Hacker Facts</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><small><font color="#FFFFFF">Conspiracy Theory</font></small></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><small><font color="#FFFFFF">Who Let the Bugs Out</font></small></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15"> <p align="center"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="8" align="center" bgcolor="#FFFFFF"> <p> </p> <p> </p> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="7" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"> </td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> <tr> <td width="100%" bordercolor="#FFFFFF" height="15" align="center" bgcolor="#FFFFFF"><font color="#FFFFFF" size="2">*</font></td> </tr> </table> <table border="0" width="100%" cellspacing="0" cellpadding="0" height="100%"> <tr> <td width="100%" height="346"></td> </tr> </table> <p> </td> </tr> </table> <table border="0" width="100%" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <p align="left"><strong>|</strong><font color="#0000FF"> Copyright 2001 TheNetworkAdministrator.com & DougChick.com |</font></td> </tr> </table> </td> </tr> </table> </body> </html> |
From: Dustin M. <du...@se...> - 2002-03-29 18:44:15
|
I've just tried Niibe-san's backport of the cache changes for the 2.4 kernel. I'm running on a SH7751 based system, and I've run into some trouble. It seems I get a kernel oops (Segmentaton fault) in __flush_cache_page when using the /bin/ps binary. The oops goes away if I simply force the CONFIG_CPU_SUBTYPE_SH7750 defines to true and use the 7750 cache method. I'm still working to getting a better idea what is causing the oops. Dustin. > -----Original Message----- > From: lin...@li... > [mailto:lin...@li...]On Behalf Of NIIBE > Yutaka > Sent: Wednesday, March 27, 2002 9:52 PM > To: lin...@li... > Subject: Re: [linuxsh-dev] cache-sh4.c > > > NIIBE Yutaka wrote: > > Yes. Besides this, we have important bug fixes (FPU thing, syscall > > restart) and feature (kernel profiling support), which should be merged > > into 2.4. > > The backport. > > Here it is. > > 2002-03-28 NIIBE Yutaka <gn...@m1...> > > * include/asm-sh/uaccess.h (strnlen_user, strlen_user): New inline > implementation. > (__clear_user): Make it external function. > > * arch/sh/mm/copy_page.S (__copy_user_page): Moved from > __copy_user_page-sh4.S. > * arch/sh/mm/__copy_user_page-sh4.S: Removed. > > * arch/sh/mm/clear_page.S (__clear_user, __flush_cache_4096): New > function. > (__clear_user_page): Moved from __clear_user_page-sh4.S. > * arch/sh/mm/__clear_user_page-sh4.S: Removed. > > * arch/sh/mm/cache-sh4.c (flush_cache_4096): New function. > (flush_dcache_page): Removed __flush_dcache_page and merged. > (__flush_icache_page, flush_cache_mm, flush_cache_range): Revert the > change of 2002-02-27. > (__flush_cache_page): New function. > (flush_cache_page): Use __flush_cache_page. > > * arch/sh/kernel/setup.c (setup_arch): Bug fix for FPU > initialization. > > * include/asm-sh/mmu_context.h (switch_mm): Remove setting/resetting > of mm->cpu_vm_mask. It's for SMP implementation. > (get_new_mmu_context): Removed. > (get_mmu_context): Merved with get_new_mmu_context. > > * include/asm-sh/hw_irq.h (sh_do_profile): Removed from here. > * arch/sh/kernel/time.c (sh_do_profile): But implemented here. > > * include/asm-sh/ptrace.h (struct pt_regs): Renamed syscall_nr to > tra. > > * arch/sh/kernel/process.c (dump_fpu, __switch_to, copy_thread): > Don't need to protect from interrupt. > (__switch_to, copy_thread): Don't check if it's init_task or not. > > * arch/sh/kernel/signal.c (do_signal): Don't set regs[0]. > Use tra (was: syscall_nr). > (restore_sigcontext): Use tra. > (handle_signal): Likewise. > (save_sigcontext_fpu): > (save_sigcontext_fpu): Use __put_user (was: __copy_to_user). > Don't need to protect from interrupt. > > * arch/sh/kernel/entry.S (COMPAT_OLD_SYSCALL_ABI): Removed. > (old_abi_system_call): Removed. > (OFF_TRA): Renamed from SYSCALL_NR. > (system_call): Use OFF_TRA and the value is now tra (was: encoded > value). > > Index: arch/sh/kernel/entry.S > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/entry.S,v > retrieving revision 1.1.1.1.2.2 > diff -u -3 -p -r1.1.1.1.2.2 entry.S > --- arch/sh/kernel/entry.S 26 Feb 2002 11:42:29 -0000 1.1.1.1.2.2 > +++ arch/sh/kernel/entry.S 28 Mar 2002 05:49:28 -0000 > @@ -15,12 +15,6 @@ > #include <linux/config.h> > > > -/* > - * Define this to turn on compatibility with the previous > - * system call ABI. This feature is not properly maintained. > - */ > -#undef COMPAT_OLD_SYSCALL_ABI > - > ! NOTE: > ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address > ! to be jumped is too far, but it causes illegal slot exception. > @@ -97,7 +91,7 @@ OFF_R6 = 24 /* New ABI: ar > OFF_R7 = 28 /* New ABI: arg3 */ > OFF_SP = (15*4) > OFF_SR = (16*4+8) > -SYSCALL_NR = (16*4+6*4) > +OFF_TRA = (16*4+6*4) > > > #define k0 r0 > @@ -345,29 +339,15 @@ system_call: > mov.l @r9, r8 > ! > ! Is the trap argument >= 0x20? (TRA will be >= 0x80) > - mov #0x20, r9 > - extu.b r9, r9 > - shll2 r9 > - cmp/hs r9, r8 > + mov #0x7f, r9 > + cmp/hi r9, r8 > bt debug_trap > ! > - mov #SYSCALL_NR, r14 > + mov #OFF_TRA, r14 > add r15, r14 > ! > -#ifdef COMPAT_OLD_SYSCALL_ABI > - mov #0x40, r9 > - cmp/hs r9, r8 > - bf/s old_abi_system_call > - nop > -#endif > ! New Syscall ABI > - add #-0x40, r8 > - shlr2 r8 > - shll8 r8 > - shll8 r8 ! r8 = num_args<<16 > - mov r3, r10 > - or r8, r10 ! Encode syscall # and # of arguments > - mov.l r10, @r14 ! set syscall_nr > + mov.l r8, @r14 ! set tra > STI() > ! > stc k_current, r11 > @@ -426,74 +406,6 @@ syscall_ret_trace: > jmp @r1 ! Call syscall_trace() which notifies superior > lds r0, pr ! Then return to ret_from_syscall() > > - > - > -#ifdef COMPAT_OLD_SYSCALL_ABI > -! Handle old ABI system call. > -! Note that ptrace(SYSCALL) is not supported for the old ABI. > -! At this point: > -! r0, r4-7 as per ABI > -! r8 = value of TRA register (= num_args<<2) > -! r14 = points to SYSCALL_NR in stack frame > -old_abi_system_call: > - mov r0, r9 ! Save system call number in r9 > - ! ! arrange for return which > pops stack > - mov.l __old_abi_syscall_ret, r10 > - lds r10, pr > - ! Build the stack frame if TRA > 0 > - mov r8, r10 > - cmp/pl r10 > - bf 0f > - mov.l @(OFF_SP,r15), r0 ! get original user stack > -7: add #-4, r10 > -4: mov.l @(r0,r10), r1 ! May cause address error exception.. > - mov.l r1, @-r15 > - cmp/pl r10 > - bt 7b > -0: > - mov.l r9, @r14 ! set syscall_nr > - STI() > - ! Call the system call handler through the table. > - ! First check for bad syscall number > - mov.l __n_sys, r10 > - cmp/hs r10, r9 > - bf 2f > - ! Bad syscall number > - rts ! return to old_abi_syscall_ret > - mov #-ENOSYS, r0 > - ! Good syscall number > -2: shll2 r9 ! x4 > - mov.l __sct, r11 > - add r11, r9 > - mov.l @r9, r11 > - jmp @r11 ! call specific syscall handler, > - nop > - > - .align 2 > -__old_abi_syscall_ret: > - .long old_abi_syscall_ret > - > - ! This code gets called on address error exception when copying > - ! syscall arguments from user stack to kernel stack. It is > - ! supposed to return -EINVAL through old_abi_syscall_ret, but it > - ! appears to have been broken for a long time in that the r0 > - ! return value will be saved into the kernel stack relative to r15 > - ! but the value of r15 is not correct partway through the loop. > - ! So the user prog is returned its old r0 value, not -EINVAL. > - ! Greg Banks 28 Aug 2000. > - .section .fixup,"ax" > -fixup_syscall_argerr: > - ! First get r15 back to > - rts > - mov #-EINVAL, r0 > - .previous > - > - .section __ex_table, "a" > - .align 2 > - .long 4b,fixup_syscall_argerr > - .previous > -#endif > - > .align 2 > __TRA: .long TRA > __syscall_trace: > @@ -529,11 +441,6 @@ ret_from_exception: > nop > > .align 2 > -#ifdef COMPAT_OLD_SYSCALL_ABI > -old_abi_syscall_ret: > - add r8, r15 ! pop off the arguments > - /* fall through */ > -#endif > syscall_ret: > mov.l r0, @(OFF_R0,r15) ! save the return value > /* fall through */ > @@ -685,7 +592,7 @@ handle_exception: > 9: mov #-1, k4 > mov.l 3f, k1 > ! Save the user registers on the stack. > - mov.l k4, @-r15 ! syscall_nr (default: -1) > + mov.l k4, @-r15 ! Set tra (default: -1) > ! > sts.l macl, @-r15 > sts.l mach, @-r15 > Index: arch/sh/kernel/process.c > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/process.c,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 process.c > --- arch/sh/kernel/process.c 15 Oct 2001 20:44:51 -0000 1.1.1.1 > +++ arch/sh/kernel/process.c 28 Mar 2002 05:49:28 -0000 > @@ -179,11 +179,7 @@ int dump_fpu(struct pt_regs *regs, elf_f > > fpvalid = tsk->used_math; > if (fpvalid) { > - unsigned long flags; > - > - save_and_cli(flags); > unlazy_fpu(tsk); > - restore_flags(flags); > memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); > } > > @@ -203,15 +199,9 @@ int copy_thread(int nr, unsigned long cl > #if defined(__SH4__) > struct task_struct *tsk = current; > > - if (tsk != &init_task) { > - unsigned long flags; > - > - save_and_cli(flags); > - unlazy_fpu(tsk); > - restore_flags(flags); > - p->thread.fpu = current->thread.fpu; > - p->used_math = tsk->used_math; > - } > + unlazy_fpu(tsk); > + 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; > @@ -257,13 +247,7 @@ void dump_thread(struct pt_regs * regs, > void __switch_to(struct task_struct *prev, struct task_struct *next) > { > #if defined(__SH4__) > - if (prev != &init_task) { > - unsigned long flags; > - > - save_and_cli(flags); > - unlazy_fpu(prev); > - restore_flags(flags); > - } > + unlazy_fpu(prev); > #endif > /* > * Restore the kernel mode register > Index: arch/sh/kernel/setup.c > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/setup.c,v > retrieving revision 1.1.1.1.2.1 > diff -u -3 -p -r1.1.1.1.2.1 setup.c > --- arch/sh/kernel/setup.c 30 Nov 2001 23:03:33 -0000 1.1.1.1.2.1 > +++ arch/sh/kernel/setup.c 28 Mar 2002 05:49:28 -0000 > @@ -485,9 +485,8 @@ void __init setup_arch(char **cmdline_p) > } > > #if defined(__SH4__) > - /* We already grab/initialized FPU in head.S. Make it > consisitent. */ > - init_task.used_math = 1; > - init_task.flags |= PF_USEDFPU; > + init_task.used_math = 0; > + init_task.flags &= ~PF_USEDFPU; > #endif > paging_init(); > } > Index: arch/sh/kernel/signal.c > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/signal.c,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 signal.c > --- arch/sh/kernel/signal.c 15 Oct 2001 20:44:52 -0000 1.1.1.1 > +++ arch/sh/kernel/signal.c 28 Mar 2002 05:49:28 -0000 > @@ -196,27 +196,20 @@ static inline int restore_sigcontext_fpu > static inline int save_sigcontext_fpu(struct sigcontext *sc) > { > struct task_struct *tsk = current; > - unsigned long flags; > - int val; > > if (!tsk->used_math) { > - val = 0; > - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); > + __put_user(0, &sc->sc_ownedfp); > return 0; > } > > - val = 1; > - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); > + __put_user(1, &sc->sc_ownedfp); > > /* This will cause a "finit" to be triggered by the next > attempted FPU operation by the 'current' process. > */ > tsk->used_math = 0; > > - save_and_cli(flags); > unlazy_fpu(tsk); > - restore_flags(flags); > - > return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, > sizeof(long)*(16*2+2)); > } > @@ -255,7 +248,7 @@ restore_sigcontext(struct pt_regs *regs, > } > #endif > > - regs->syscall_nr = -1; /* disable syscall checks */ > + regs->tra = -1; /* disable syscall checks */ > err |= __get_user(*r0_p, &sc->sc_regs[0]); > return err; > } > @@ -524,7 +517,7 @@ handle_signal(unsigned long sig, struct > siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) > { > /* Are we from a system call? */ > - if (regs->syscall_nr >= 0) { > + if (regs->tra >= 0) { > /* If so, check system call restarting.. */ > switch (regs->regs[0]) { > case -ERESTARTNOHAND: > @@ -538,7 +531,6 @@ handle_signal(unsigned long sig, struct > } > /* fallthrough */ > case -ERESTARTNOINTR: > - regs->regs[0] = regs->syscall_nr; > regs->pc -= 2; > } > } > @@ -685,12 +677,11 @@ int do_signal(struct pt_regs *regs, sigs > } > > /* Did we come from a system call? */ > - if (regs->syscall_nr >= 0) { > + if (regs->tra >= 0) { > /* Restart the system call - no handlers present */ > if (regs->regs[0] == -ERESTARTNOHAND || > regs->regs[0] == -ERESTARTSYS || > regs->regs[0] == -ERESTARTNOINTR) { > - regs->regs[0] = regs->syscall_nr; > regs->pc -= 2; > } > } > Index: arch/sh/kernel/time.c > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/time.c,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 time.c > --- arch/sh/kernel/time.c 15 Oct 2001 20:44:50 -0000 1.1.1.1 > +++ arch/sh/kernel/time.c 28 Mar 2002 05:49:28 -0000 > @@ -176,6 +176,25 @@ void do_settimeofday(struct timeval *tv) > /* last time the RTC clock got updated */ > static long last_rtc_update; > > +static __inline__ void sh_do_profile (unsigned long pc) > +{ > + extern int _stext; > + > + if (!prof_buffer) > + return; > + > + pc -= (unsigned long) &_stext; > + pc >>= prof_shift; > + /* > + * Don't ignore out-of-bounds PC values silently, > + * put them into the last histogram slot, so if > + * present, they will show up as a sharp peak. > + */ > + if (pc > prof_len-1) > + pc = prof_len-1; > + prof_buffer[pc]++; > +} > + > /* > * timer_interrupt() needs to keep up the real-time clock, > * as well as call the "do_timer()" routine every clocktick > Index: arch/sh/mm/Makefile > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/Makefile,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 Makefile > --- arch/sh/mm/Makefile 15 Oct 2001 20:44:53 -0000 1.1.1.1 > +++ arch/sh/mm/Makefile 28 Mar 2002 05:49:28 -0000 > @@ -11,7 +11,7 @@ O_TARGET := mm.o > obj-y := init.o fault.o extable.o clear_page.o copy_page.o > > obj-$(CONFIG_CPU_SH3) += cache-sh3.o > -obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o > __copy_user_page-sh4.o ioremap.o > +obj-$(CONFIG_CPU_SH4) += cache-sh4.o ioremap.o > > USE_STANDARD_AS_RULE := true > > Index: arch/sh/mm/cache-sh4.c > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v > retrieving revision 1.1.1.1.2.3 > diff -u -3 -p -r1.1.1.1.2.3 cache-sh4.c > --- arch/sh/mm/cache-sh4.c 22 Mar 2002 14:02:09 -0000 1.1.1.1.2.3 > +++ arch/sh/mm/cache-sh4.c 28 Mar 2002 05:49:28 -0000 > @@ -1,9 +1,8 @@ > /* $Id: cache-sh4.c,v 1.1.1.1.2.3 2002/03/22 14:02:09 gniibe Exp $ > * > - * linux/arch/sh/mm/cache.c > + * linux/arch/sh/mm/cache-sh4.c > * > - * Copyright (C) 1999, 2000 Niibe Yutaka > - * Copyright (C) 2001, 2002 Paul Mundt > + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka > */ > > #include <linux/config.h> > @@ -208,55 +207,34 @@ void flush_cache_sigtramp(unsigned long > restore_flags(flags); > } > > -/* > - * Writeback&Invalidate the D-cache of the page > - */ > -static void __flush_dcache_page(unsigned long phys) > -{ > - unsigned long addr, data; > - unsigned long flags; > - > - phys |= CACHE_VALID; > - > - save_and_cli(flags); > - jump_to_P2(); > - > - /* Loop all the D-cache */ > - for (addr = CACHE_OC_ADDRESS_ARRAY; > - addr < (CACHE_OC_ADDRESS_ARRAY > - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); > - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { > - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); > - if (data == phys) > - ctrl_outl(0, addr); > - } > - > - back_to_P1(); > - restore_flags(flags); > -} > - > -static void __flush_icache_page(unsigned long phys) > +static inline void flush_cache_4096(unsigned long start, > + unsigned long phys) > { > +#if defined(CONFIG_CPU_SUBTYPE_SH7750) > + register unsigned long addr __asm__ ("r4"); > + register unsigned long data __asm__ ("r0"); > + register unsigned long __r5 __asm__ ("r5") = phys; > + register unsigned long __r6 __asm__ ("r6") = > (0x1ffff000|CACHE_VALID); > + register unsigned long __r7 __asm__ ("r7") = 0; > + extern void __flush_cache_4096(unsigned long, unsigned long); > + > + asm volatile("jsr @%1; nop" > + : "=r" (addr), "=r" (data) > + : "0" (start), "1" (__flush_cache_4096 + 0x20000000), > + "r" (__r5), "r" (__r6), "r" (__r7) > + : "pr"); > +#else > + /* > + * SH7751 and ST40 have no restriction to handle cache. > + * (While SH7750 must do that at P2 area.) > + */ > unsigned long addr, data; > - unsigned long flags; > - > - phys |= CACHE_VALID; > - > - save_and_cli(flags); > - jump_to_P2(); > - > - /* Loop all the I-cache */ > - for (addr = CACHE_IC_ADDRESS_ARRAY; > - addr < (CACHE_IC_ADDRESS_ARRAY > - +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); > - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { > + for (addr = start; addr < start + 4096; addr += 32) { > data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); > if (data == phys) > ctrl_outl(0, addr); > } > - > - back_to_P1(); > - restore_flags(flags); > +#endif > } > > /* > @@ -265,8 +243,22 @@ static void __flush_icache_page(unsigned > */ > void flush_dcache_page(struct page *page) > { > - if (test_bit(PG_mapped, &page->flags)) > - __flush_dcache_page(PHYSADDR(page_address(page))); > + if (test_bit(PG_mapped, &page->flags)) { > + unsigned long phys = PHYSADDR(page_address(page)); > + unsigned long flags; > + > + phys |= CACHE_VALID; > + > + save_and_cli(flags); > + > + /* Loop all the D-cache */ > + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); > + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); > + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); > + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys); > + > + restore_flags(flags); > + } > } > > void flush_cache_all(void) > @@ -298,15 +290,43 @@ void flush_cache_mm(struct mm_struct *mm > * FIXME: Really, the optimal solution here would be able > to flush out > * individual lines created by the specified context, but this isn't > * feasible for a number of architectures (such as MIPS, and some > - * SPARC) .. is this possible for SuperH? (This is a > non-issue if the > - * SH4 cache is configured in write-through mode). > + * SPARC) .. is this possible for SuperH? > * > - * In the meantime, we'll just flush all of the caches if we have a > - * valid mm context.. this seems to be the simplest way to avoid at > - * least a few wasted cache flushes. -Lethal > + * In the meantime, we'll just flush all of the caches.. this > + * seems to be the simplest way to avoid at least a few wasted > + * cache flushes. -Lethal > */ > - if (mm->context != 0) > - flush_cache_all(); > + flush_cache_all(); > +} > + > +static void __flush_cache_page(struct vm_area_struct *vma, > + unsigned long address, > + unsigned long phys) > +{ > + unsigned long flags; > + > + phys |= CACHE_VALID; > + save_and_cli(flags); > + > + /* We only need to flush D-cache when we have alias */ > + if ((address^phys) & CACHE_ALIAS) { > + /* Loop 4K of the D-cache */ > + flush_cache_4096( > + CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), > + phys); > + /* Loop another 4K of the D-cache */ > + flush_cache_4096( > + CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), > + phys); > + } > + > + if (vma->vm_flags & VM_EXEC) > + /* Loop 4K (half) of the I-cache */ > + flush_cache_4096( > + CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), > + phys); > + > + restore_flags(flags); > } > > /* > @@ -321,39 +341,15 @@ 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; > - > - if (mm->context == 0) > - return; > - > - start &= PAGE_MASK; > - > - if (!find_vma(mm, start)) > - return; > - if (mm->context != current->active_mm->context) { > - flush_cache_all(); > - } else { > - pgd_t *pgd; > - pmd_t *pmd; > - pte_t *pte; > - > - save_and_cli(flags); > - jump_to_P2(); > - > - for (start; start < end; start += PAGE_SIZE) { > - pgd = pgd_offset(mm, start); > - pmd = pmd_offset(pgd, start); > - pte = pte_offset(pmd, start); > - > - if (pte_val(*pte) & _PAGE_PRESENT) { > - __flush_icache_page(start); > - __flush_dcache_page(start); > - } > - } > - > - back_to_P1(); > - restore_flags(flags); > - } > + /* > + * We could call flush_cache_page for the pages of these > + * range, but it's really time consuming (we have to scan the > + * caches all the time...). > + * > + * We can't use A-bit magic, as there's the case we don't have > + * valid entry on TLB. > + */ > + flush_cache_all(); > } > > /* > @@ -367,8 +363,7 @@ void flush_cache_page(struct vm_area_str > pmd_t *pmd; > pte_t *pte; > pte_t entry; > - unsigned long phys, addr, data; > - unsigned long flags; > + unsigned long phys; > > dir = pgd_offset(vma->vm_mm, address); > pmd = pmd_offset(dir, address); > @@ -376,49 +371,11 @@ void flush_cache_page(struct vm_area_str > return; > pte = pte_offset(pmd, address); > entry = *pte; > - if (pte_none(entry) || !pte_present(entry)) > + if (!(pte_val(entry) & _PAGE_PRESENT)) > return; > > phys = pte_val(entry)&PTE_PHYS_MASK; > - > - phys |= CACHE_VALID; > - save_and_cli(flags); > - jump_to_P2(); > - > - /* We only need to flush D-cache when we have alias */ > - if ((address^phys) & CACHE_ALIAS) { > - /* Loop 4K of the D-cache */ > - for (addr = CACHE_OC_ADDRESS_ARRAY | (address & > CACHE_ALIAS); > - addr < (CACHE_OC_ADDRESS_ARRAY + (address & > CACHE_ALIAS) > - > +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); > - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { > - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); > - if (data == phys) > - ctrl_outl(0, addr); > - } > - /* Loop another 4K of the D-cache */ > - for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS); > - addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) > - > +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); > - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { > - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); > - if (data == phys) > - ctrl_outl(0, addr); > - } > - } > - > - if (vma->vm_flags & VM_EXEC) > - /* Loop 4K of the I-cache */ > - for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000); > - addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000)) > - > +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT)); > - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { > - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); > - if (data == phys) > - ctrl_outl(0, addr); > - } > - back_to_P1(); > - restore_flags(flags); > + __flush_cache_page(vma, address, phys); > } > > /* > Index: arch/sh/mm/clear_page.S > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 clear_page.S > --- arch/sh/mm/clear_page.S 15 Oct 2001 20:44:53 -0000 1.1.1.1 > +++ arch/sh/mm/clear_page.S 28 Mar 2002 05:49:28 -0000 > @@ -1,10 +1,13 @@ > /* $Id: clear_page.S,v 1.1.1.1 2001/10/15 20:44:53 mrbrown Exp $ > * > - * clear_page implementation of SuperH > + * __clear_user_page, __clear_user, clear_page implementation of SuperH > * > - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima > + * Copyright (C) 2001 Kaz Kojima > + * Copyright (C) 2001, 2002 Niibe Yutaka > * > */ > +#include <linux/config.h> > +#include <linux/linkage.h> > > /* > * clear_page > @@ -18,7 +21,6 @@ > * r4 --- to > * r5 --- to + 4096 > */ > -#include <linux/linkage.h> > ENTRY(clear_page) > mov r4,r5 > mov.w .Llimit,r0 > @@ -50,3 +52,154 @@ ENTRY(clear_page) > rts > nop > .Llimit: .word (4096-28) > + > +ENTRY(__clear_user) > + ! > + mov #0, r0 > + mov #0xe0, r1 ! 0xffffffe0 > + ! > + ! r4..r4&~32 -------- not aligned [ Area 0 ] > + ! r4&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] > + ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] > + ! > + ! Clear area 0 > + mov r4, r2 > + and r1, r2 > + cmp/eq r4, r2 > + bt/s area1 > + mov r4, r3 > + sub r2, r3 > + mov r4, r2 > + ! > +l0: dt r3 > +0: mov.b r0, @r2 > + bf/s l0 > + add #1, r2 > + ! > + mov r4, r3 > + add r5, r3 > + and r1, r3 > + ! > + ! Clear area 1 > +area1: > +#if defined(__SH4__) > +1: movca.l r0, @r2 > +#else > +1: mov.l r0, @r2 > +#endif > + add #4, r2 > +2: mov.l r0, @r2 > + add #4, r2 > +3: mov.l r0, @r2 > + add #4, r2 > +4: mov.l r0, @r2 > + add #4, r2 > +5: mov.l r0, @r2 > + add #4, r2 > +6: mov.l r0, @r2 > + add #4, r2 > +7: mov.l r0, @r2 > + add #4, r2 > +8: mov.l r0, @r2 > + add #4, r2 > + cmp/hi r2, r3 > + bt/s 1b > + nop > + ! > + ! Clear area 2 > + add r5, r4 > + cmp/eq r4, r2 > + bt/s done > + sub r2, r4 > +l2: dt r4 > +9: mov.b r0, @r2 > + bf/s l2 > + add #1, r2 > + ! > +done: rts > + nop ! return 0 as normal return > + > + ! return the number of bytes remained > +bad_clear_user: > + mov r4, r0 > + mov r5, r0 > + rts > + sub r2, r0 > + > +.section __ex_table,"a" > + .align 2 > + .long 0b, bad_clear_user > + .long 1b, bad_clear_user > + .long 2b, bad_clear_user > + .long 3b, bad_clear_user > + .long 4b, bad_clear_user > + .long 5b, bad_clear_user > + .long 6b, bad_clear_user > + .long 7b, bad_clear_user > + .long 8b, bad_clear_user > + .long 9b, bad_clear_user > +.previous > + > +#if defined(__SH4__) > +/* > + * __clear_user_page > + * @to: P1 address (with same color) > + * @orig_to: P1 address > + * > + * void __clear_user_page(void *to, void *orig_to) > + */ > + > +/* > + * r0 --- scratch > + * r4 --- to > + * r5 --- orig_to > + * r6 --- to + 4096 > + */ > +ENTRY(__clear_user_page) > + mov.w .L4096,r0 > + mov r4,r6 > + add r0,r6 > + mov #0,r0 > + ! > +1: ocbi @r5 > + add #32,r5 > + movca.l r0,@r4 > + mov r4,r1 > + add #32,r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + mov.l r0,@-r4 > + add #28,r4 > + cmp/eq r6,r4 > + bf/s 1b > + ocbwb @r1 > + ! > + rts > + nop > +.L4096: .word 4096 > + > +#if defined(CONFIG_CPU_SUBTYPE_SH7750) > +ENTRY(__flush_cache_4096) > + .rept 128 > + mov.l @r4,r0 > + and r6,r0 > + cmp/eq r5,r0 > + bf 1f > + mov.l r7,@r4 > +1: add #32,r4 > + .endr > + nop > + nop > + nop > + nop > + nop > + nop > + nop > + rts > + nop > +#endif > +#endif > Index: arch/sh/mm/copy_page.S > =================================================================== > RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/copy_page.S,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 copy_page.S > --- arch/sh/mm/copy_page.S 15 Oct 2001 20:44:53 -0000 1.1.1.1 > +++ arch/sh/mm/copy_page.S 28 Mar 2002 05:49:28 -0000 > @@ -1,10 +1,11 @@ > /* $Id: copy_page.S,v 1.1.1.1 2001/10/15 20:44:53 mrbrown Exp $ > * > - * copy_page implementation of SuperH > + * copy_page, __copy_user_page implementation of SuperH > * > * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima > * > */ > +#include <linux/linkage.h> > > /* > * copy_page > @@ -21,7 +22,6 @@ > * r10 --- to > * r11 --- from > */ > -#include <linux/linkage.h> > ENTRY(copy_page) > mov.l r8,@-r15 > mov.l r10,@-r15 > @@ -66,4 +66,67 @@ ENTRY(copy_page) > mov.l @r15+,r8 > rts > nop > + > +#if defined(__SH4__) > +/* > + * __copy_user_page > + * @to: P1 address (with same color) > + * @from: P1 address > + * @orig_to: P1 address > + * > + * void __copy_user_page(void *to, void *from, void *orig_to) > + */ > + > +/* > + * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch > + * r8 --- from + 4096 > + * r9 --- orig_to > + * r10 --- to > + * r11 --- from > + */ > +#include <linux/linkage.h> > +ENTRY(__copy_user_page) > + mov.l r8,@-r15 > + mov.l r9,@-r15 > + mov.l r10,@-r15 > + mov.l r11,@-r15 > + mov r4,r10 > + mov r5,r11 > + mov r6,r9 > + mov r5,r8 > + mov.w .L4096,r0 > + add r0,r8 > + ! > +1: ocbi @r9 > + add #32,r9 > + mov.l @r11+,r0 > + mov.l @r11+,r1 > + mov.l @r11+,r2 > + mov.l @r11+,r3 > + mov.l @r11+,r4 > + mov.l @r11+,r5 > + mov.l @r11+,r6 > + mov.l @r11+,r7 > + movca.l r0,@r10 > + mov r10,r0 > + add #32,r10 > + mov.l r7,@-r10 > + mov.l r6,@-r10 > + mov.l r5,@-r10 > + mov.l r4,@-r10 > + mov.l r3,@-r10 > + mov.l r2,@-r10 > + mov.l r1,@-r10 > + ocbwb @r0 > + cmp/eq r11,r8 > + bf/s 1b > + add #28,r10 > + ! > + mov.l @r15+,r11 > + mov.l @r15+,r10 > + mov.l @r15+,r9 > + mov.l @r15+,r8 > + rts > + nop > +#endif > .L4096: .word 4096 > Index: include/asm-sh/hw_irq.h > =================================================================== > RCS file: /cvsroot/linuxsh/linux/include/asm-sh/hw_irq.h,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 hw_irq.h > --- include/asm-sh/hw_irq.h 15 Oct 2001 20:45:08 -0000 1.1.1.1 > +++ include/asm-sh/hw_irq.h 28 Mar 2002 05:49:28 -0000 > @@ -1,6 +1,4 @@ > #ifndef __ASM_SH_HW_IRQ_H > #define __ASM_SH_HW_IRQ_H > -static __inline__ void sh_do_profile (unsigned long pc) {/*Not > implemented yet*/} > - > static __inline__ void hw_resend_irq(struct hw_interrupt_type > *h, unsigned int i) { /* Nothing to do */ } > #endif /* __ASM_SH_HW_IRQ_H */ > Index: include/asm-sh/mmu_context.h > =================================================================== > RCS file: /cvsroot/linuxsh/linux/include/asm-sh/mmu_context.h,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 mmu_context.h > --- include/asm-sh/mmu_context.h 15 Oct 2001 20:45:10 -0000 > 1.1.1.1 > +++ include/asm-sh/mmu_context.h 28 Mar 2002 05:49:28 -0000 > @@ -29,19 +29,32 @@ extern unsigned long mmu_context_cache; > */ > #define MMU_VPN_MASK 0xfffff000 > > +/* > + * Get MMU context if needed. > + */ > static __inline__ void > -get_new_mmu_context(struct mm_struct *mm) > +get_mmu_context(struct mm_struct *mm) > { > extern void flush_tlb_all(void); > + unsigned long mc = mmu_context_cache; > > - unsigned long mc = ++mmu_context_cache; > + /* Check if we have old version of context. */ > + if (((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0) > + /* It's up to date, do nothing */ > + return; > > + /* It's old, we need to get new context with new version. */ > + mc = ++mmu_context_cache; > if (!(mc & MMU_CONTEXT_ASID_MASK)) { > - /* We exhaust ASID of this version. > - Flush all TLB and start new cycle. */ > + /* > + * We exhaust ASID of this version. > + * Flush all TLB and start new cycle. > + */ > flush_tlb_all(); > - /* Fix version if needed. > - Note that we avoid version #0 to distingush > NO_CONTEXT. */ > + /* > + * Fix version; Note that we avoid version #0 > + * to distingush NO_CONTEXT. > + */ > if (!mc) > mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION; > } > @@ -49,21 +62,6 @@ get_new_mmu_context(struct mm_struct *mm > } > > /* > - * Get MMU context if needed. > - */ > -static __inline__ void > -get_mmu_context(struct mm_struct *mm) > -{ > - if (mm) { > - unsigned long mc = mmu_context_cache; > - /* Check if we have old version of context. > - If it's old, we need to get new context with new > version. */ > - if ((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) > - get_new_mmu_context(mm); > - } > -} > - > -/* > * Initialize the context related info for a new mm_struct > * instance. > */ > @@ -169,8 +167,6 @@ static __inline__ void switch_mm(struct > if (prev != next) { > unsigned long __pgdir = (unsigned long)next->pgd; > > - clear_bit(cpu, &prev->cpu_vm_mask); > - set_bit(cpu, &next->cpu_vm_mask); > __asm__ __volatile__("mov.l %0, %1" > : /* no output */ > : "r" (__pgdir), "m" (__m(MMU_TTB))); > @@ -185,4 +181,5 @@ static __inline__ void > enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, > unsigned cpu) > { > } > + > #endif /* __ASM_SH_MMU_CONTEXT_H */ > Index: include/asm-sh/ptrace.h > =================================================================== > RCS file: /cvsroot/linuxsh/linux/include/asm-sh/ptrace.h,v > retrieving revision 1.1.1.1 > diff -u -3 -p -r1.1.1.1 ptrace.h > --- include/asm-sh/ptrace.h 15 Oct 2001 20:45:11 -0000 1.1.1.1 > +++ include/asm-sh/ptrace.h 28 Mar 2002 05:49:28 -0000 > @@ -61,7 +61,7 @@ struct pt_regs { > unsigned long gbr; > unsigned long mach; > unsigned long macl; > - long syscall_nr; > + long tra; > }; > > #ifdef __KERNEL__ > Index: include/asm-sh/uaccess.h > =================================================================== > RCS file: /cvsroot/linuxsh/linux/include/asm-sh/uaccess.h,v > retrieving revision 1.1.1.1.2.1 > diff -u -3 -p -r1.1.1.1.2.1 uaccess.h > --- include/asm-sh/uaccess.h 3 Nov 2001 00:52:47 -0000 1.1.1.1.2.1 > +++ include/asm-sh/uaccess.h 28 Mar 2002 05:49:28 -0000 > @@ -308,39 +308,11 @@ __copy_res; }) > __copy_user((void *)(to), \ > (void *)(from), n) > > -/* XXX: Not sure it works well.. > - should be such that: 4byte clear and the rest. */ > -static __inline__ __kernel_size_t > -__clear_user(void *addr, __kernel_size_t size) > -{ > - unsigned long __a; > - > - __asm__ __volatile__( > - "9:\n\t" > - "dt %0\n" > - "1:\n\t" > - "mov.b %4, @%1\n\t" > - "bf/s 9b\n\t" > - " add #1, %1\n" > - "2:\n" > - ".section .fixup,\"ax\"\n" > - "3:\n\t" > - "mov.l 4f, %1\n\t" > - "jmp @%1\n\t" > - " nop\n" > - ".balign 4\n" > - "4: .long 2b\n" > - ".previous\n" > - ".section __ex_table,\"a\"\n" > - " .balign 4\n" > - " .long 1b,3b\n" > - ".previous" > - : "=r" (size), "=r" (__a) > - : "0" (size), "1" (addr), "r" (0) > - : "memory", "t"); > - > - return size; > -} > +/* > + * Clear the area and return remaining number of bytes > + * (on failure. Usually it's 0.) > + */ > +extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); > > #define clear_user(addr,n) ({ \ > void * __cl_addr = (addr); \ > @@ -396,8 +368,6 @@ if(__access_ok(__sfu_src, __sfu_count)) > __sfu_res = __strncpy_from_user((unsigned long) (dest), > __sfu_src, __sfu_count); \ > } __sfu_res; }) > > -#define strlen_user(str) strnlen_user(str, ~0UL >> 1) > - > /* > * Return the size of a string (including the ending 0!) > */ > @@ -436,10 +406,18 @@ static __inline__ long __strnlen_user(co > > static __inline__ long strnlen_user(const char *s, long n) > { > - if (!__addr_ok(s)) > + if (!access_ok(VERIFY_READ, s, n)) > return 0; > else > return __strnlen_user(s, n); > +} > + > +static __inline__ long strlen_user(const char *s) > +{ > + if (!access_ok(VERIFY_READ, s, 0)) > + return 0; > + else > + return __strnlen_user(s, ~0UL >> 1); > } > > struct exception_table_entry > > _______________________________________________ > linuxsh-dev mailing list > lin...@li... > https://lists.sourceforge.net/lists/listinfo/linuxsh-dev > > |
From: NIIBE Y. <gn...@m1...> - 2002-03-29 02:04:47
|
This fixes flush_cache_range performance issue. Now, it's comparable to flush_cache_range = flush_cache_all implementation (when measured process spawn test). (That is, two times faster.) Besides, flush_cache_all has been improved, so that it doesn't hold interrupt off. 2002-03-29 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache-sh4.c (flush_cache_4096_nocheck): New function. (flush_icache_all): New function. (flush_cache_all): Use flush_icache_all. Don't need to protect from interrupt as we don't flush dcache by writing CCR. (flush_cache_range): Don't call __flush_cache_page, but call flush_cache_4096_nocheck. * arch/sh/mm/clear_page.S (__flush_cache_4096_nocheck): New function. Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.9 diff -u -3 -p -r1.9 cache-sh4.c --- arch/sh/mm/cache-sh4.c 29 Mar 2002 00:02:04 -0000 1.9 +++ arch/sh/mm/cache-sh4.c 29 Mar 2002 01:58:44 -0000 @@ -208,6 +208,33 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } +static void flush_cache_4096_nocheck(unsigned long start) +{ +#if defined(CONFIG_CPU_SUBTYPE_SH7750) + register unsigned long __r0 __asm__ ("r0") = 0; + register unsigned long __r1 __asm__ ("r1") = 128; + register unsigned long __r4 __asm__ ("r4"); + register unsigned long __r5 __asm__ ("r5"); + register unsigned long __r6 __asm__ ("r6"); + register unsigned long __r7 __asm__ ("r7"); + extern void __flush_cache_4096_nocheck(unsigned long); + + asm volatile("jsr @%7; nop" + : "=&r" (__r4), "=&r" (__r5), "=&r" (__r6), "=&r" (__r7) + : "0" (start), "r" (__r0), "r" (__r1), + "r" (__flush_cache_4096_nocheck + 0x20000000) + : "pr"); +#else + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr; + for (addr = start; addr < start + 4096; addr += 32) + ctrl_outl(0, addr); +#endif +} + static inline void flush_cache_4096(unsigned long start, unsigned long phys) { @@ -262,25 +289,54 @@ void flush_dcache_page(struct page *page } } -void flush_cache_all(void) +static inline void flush_icache_all(void) { - extern unsigned long empty_zero_page[1024]; unsigned long flags; - unsigned long addr; save_and_cli(flags); + jump_to_P2(); + /* Flush I-cache */ + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); + back_to_P1(); + restore_flags(flags); +} + +void flush_cache_all(void) +{ + extern unsigned long empty_zero_page[1024]; /* Prefetch the data to write back D-cache */ + +#if C_IMPLEMENTATION + unsigned long addr; + for (addr = (unsigned long)empty_zero_page; addr < (unsigned long)empty_zero_page + 1024*16; addr += L1_CACHE_BYTES) asm volatile("pref @%0"::"r" (addr)); - - jump_to_P2(); - /* Flush D-cache/I-cache */ - ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_P1(); - restore_flags(flags); +#else + unsigned long a0, a1, a2, a3, cnt; + asm volatile( + "mov %0, %1; add #32, %1\n\t" + "mov %0, %2; add #64, %2\n\t" + "mov %1, %3; add #64, %3\n\t" + "1:\n\t" + "pref @%0\n\t" + "dt %4\n\t" + "pref @%1\n\t" + "add %5, %0\n\t" + "pref @%2\n\t" + "add %5, %1\n\t" + "pref @%3\n\t" + "add %5, %2\n\t" + "bf/s 1b\n\t" + " add %5, %3" + : "=&r" (a0), "=&r" (a1), "=&r" (a2), "=&r" (a3), "=&r" (cnt) + : "r" (32*4), "0" (empty_zero_page), "4" (1024*16/32/4) + : "t"); + } +#endif + flush_icache_all(); } void flush_cache_mm(struct mm_struct *mm) @@ -348,6 +404,7 @@ void flush_cache_range(struct vm_area_st pte_t *pte; pte_t entry; unsigned long phys; + unsigned long d = 0; dir = pgd_offset(vma->vm_mm, p); pmd = pmd_offset(dir, p); @@ -364,13 +421,29 @@ void flush_cache_range(struct vm_area_st entry = *pte; if ((pte_val(entry) & _PAGE_PRESENT)) { phys = pte_val(entry)&PTE_PHYS_MASK; - __flush_cache_page(vma, p, phys); + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } } pte++; p += PAGE_SIZE; } while (p < end && (unsigned long)pte & PAGE_MASK); pmd++; } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY); + if (d & 2) + flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x1000); + if (d & 4) + flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x2000); + if (d & 8) + flush_cache_4096_nocheck(CACHE_OC_ADDRESS_ARRAY | 0x3000); + if (vma->vm_flags & VM_EXEC) + flush_icache_all(); } /* Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.3 diff -u -3 -p -r1.3 clear_page.S --- arch/sh/mm/clear_page.S 29 Mar 2002 00:02:04 -0000 1.3 +++ arch/sh/mm/clear_page.S 29 Mar 2002 01:58:44 -0000 @@ -201,5 +201,32 @@ ENTRY(__flush_cache_4096) nop rts nop + +ENTRY(__flush_cache_4096_nocheck) + mov r4,r5 + mov r4,r6 + mov r4,r7 + add #32,r5 + add #-64,r6 + add #-32,r7 + .rept 32 + mov.l r0,@r4 + add r1,r6 + mov.l r0,@r5 + add r1,r7 + mov.l r0,@r6 + add r1,r4 + mov.l r0,@r7 + add r1,r5 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop #endif #endif |
From: NIIBE Y. <gn...@m1...> - 2002-03-28 05:51:46
|
NIIBE Yutaka wrote: > Yes. Besides this, we have important bug fixes (FPU thing, syscall > restart) and feature (kernel profiling support), which should be merged > into 2.4. The backport. Here it is. 2002-03-28 NIIBE Yutaka <gn...@m1...> * include/asm-sh/uaccess.h (strnlen_user, strlen_user): New inline implementation. (__clear_user): Make it external function. * arch/sh/mm/copy_page.S (__copy_user_page): Moved from __copy_user_page-sh4.S. * arch/sh/mm/__copy_user_page-sh4.S: Removed. * arch/sh/mm/clear_page.S (__clear_user, __flush_cache_4096): New function. (__clear_user_page): Moved from __clear_user_page-sh4.S. * arch/sh/mm/__clear_user_page-sh4.S: Removed. * arch/sh/mm/cache-sh4.c (flush_cache_4096): New function. (flush_dcache_page): Removed __flush_dcache_page and merged. (__flush_icache_page, flush_cache_mm, flush_cache_range): Revert the change of 2002-02-27. (__flush_cache_page): New function. (flush_cache_page): Use __flush_cache_page. * arch/sh/kernel/setup.c (setup_arch): Bug fix for FPU initialization. * include/asm-sh/mmu_context.h (switch_mm): Remove setting/resetting of mm->cpu_vm_mask. It's for SMP implementation. (get_new_mmu_context): Removed. (get_mmu_context): Merved with get_new_mmu_context. * include/asm-sh/hw_irq.h (sh_do_profile): Removed from here. * arch/sh/kernel/time.c (sh_do_profile): But implemented here. * include/asm-sh/ptrace.h (struct pt_regs): Renamed syscall_nr to tra. * arch/sh/kernel/process.c (dump_fpu, __switch_to, copy_thread): Don't need to protect from interrupt. (__switch_to, copy_thread): Don't check if it's init_task or not. * arch/sh/kernel/signal.c (do_signal): Don't set regs[0]. Use tra (was: syscall_nr). (restore_sigcontext): Use tra. (handle_signal): Likewise. (save_sigcontext_fpu): (save_sigcontext_fpu): Use __put_user (was: __copy_to_user). Don't need to protect from interrupt. * arch/sh/kernel/entry.S (COMPAT_OLD_SYSCALL_ABI): Removed. (old_abi_system_call): Removed. (OFF_TRA): Renamed from SYSCALL_NR. (system_call): Use OFF_TRA and the value is now tra (was: encoded value). Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/entry.S,v retrieving revision 1.1.1.1.2.2 diff -u -3 -p -r1.1.1.1.2.2 entry.S --- arch/sh/kernel/entry.S 26 Feb 2002 11:42:29 -0000 1.1.1.1.2.2 +++ arch/sh/kernel/entry.S 28 Mar 2002 05:49:28 -0000 @@ -15,12 +15,6 @@ #include <linux/config.h> -/* - * Define this to turn on compatibility with the previous - * system call ABI. This feature is not properly maintained. - */ -#undef COMPAT_OLD_SYSCALL_ABI - ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address ! to be jumped is too far, but it causes illegal slot exception. @@ -97,7 +91,7 @@ OFF_R6 = 24 /* New ABI: ar OFF_R7 = 28 /* New ABI: arg3 */ OFF_SP = (15*4) OFF_SR = (16*4+8) -SYSCALL_NR = (16*4+6*4) +OFF_TRA = (16*4+6*4) #define k0 r0 @@ -345,29 +339,15 @@ system_call: mov.l @r9, r8 ! ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x20, r9 - extu.b r9, r9 - shll2 r9 - cmp/hs r9, r8 + mov #0x7f, r9 + cmp/hi r9, r8 bt debug_trap ! - mov #SYSCALL_NR, r14 + mov #OFF_TRA, r14 add r15, r14 ! -#ifdef COMPAT_OLD_SYSCALL_ABI - mov #0x40, r9 - cmp/hs r9, r8 - bf/s old_abi_system_call - nop -#endif ! New Syscall ABI - add #-0x40, r8 - shlr2 r8 - shll8 r8 - shll8 r8 ! r8 = num_args<<16 - mov r3, r10 - or r8, r10 ! Encode syscall # and # of arguments - mov.l r10, @r14 ! set syscall_nr + mov.l r8, @r14 ! set tra STI() ! stc k_current, r11 @@ -426,74 +406,6 @@ syscall_ret_trace: jmp @r1 ! Call syscall_trace() which notifies superior lds r0, pr ! Then return to ret_from_syscall() - - -#ifdef COMPAT_OLD_SYSCALL_ABI -! Handle old ABI system call. -! Note that ptrace(SYSCALL) is not supported for the old ABI. -! At this point: -! r0, r4-7 as per ABI -! r8 = value of TRA register (= num_args<<2) -! r14 = points to SYSCALL_NR in stack frame -old_abi_system_call: - mov r0, r9 ! Save system call number in r9 - ! ! arrange for return which pops stack - mov.l __old_abi_syscall_ret, r10 - lds r10, pr - ! Build the stack frame if TRA > 0 - mov r8, r10 - cmp/pl r10 - bf 0f - mov.l @(OFF_SP,r15), r0 ! get original user stack -7: add #-4, r10 -4: mov.l @(r0,r10), r1 ! May cause address error exception.. - mov.l r1, @-r15 - cmp/pl r10 - bt 7b -0: - mov.l r9, @r14 ! set syscall_nr - STI() - ! Call the system call handler through the table. - ! First check for bad syscall number - mov.l __n_sys, r10 - cmp/hs r10, r9 - bf 2f - ! Bad syscall number - rts ! return to old_abi_syscall_ret - mov #-ENOSYS, r0 - ! Good syscall number -2: shll2 r9 ! x4 - mov.l __sct, r11 - add r11, r9 - mov.l @r9, r11 - jmp @r11 ! call specific syscall handler, - nop - - .align 2 -__old_abi_syscall_ret: - .long old_abi_syscall_ret - - ! This code gets called on address error exception when copying - ! syscall arguments from user stack to kernel stack. It is - ! supposed to return -EINVAL through old_abi_syscall_ret, but it - ! appears to have been broken for a long time in that the r0 - ! return value will be saved into the kernel stack relative to r15 - ! but the value of r15 is not correct partway through the loop. - ! So the user prog is returned its old r0 value, not -EINVAL. - ! Greg Banks 28 Aug 2000. - .section .fixup,"ax" -fixup_syscall_argerr: - ! First get r15 back to - rts - mov #-EINVAL, r0 - .previous - - .section __ex_table, "a" - .align 2 - .long 4b,fixup_syscall_argerr - .previous -#endif - .align 2 __TRA: .long TRA __syscall_trace: @@ -529,11 +441,6 @@ ret_from_exception: nop .align 2 -#ifdef COMPAT_OLD_SYSCALL_ABI -old_abi_syscall_ret: - add r8, r15 ! pop off the arguments - /* fall through */ -#endif syscall_ret: mov.l r0, @(OFF_R0,r15) ! save the return value /* fall through */ @@ -685,7 +592,7 @@ handle_exception: 9: mov #-1, k4 mov.l 3f, k1 ! Save the user registers on the stack. - mov.l k4, @-r15 ! syscall_nr (default: -1) + mov.l k4, @-r15 ! Set tra (default: -1) ! sts.l macl, @-r15 sts.l mach, @-r15 Index: arch/sh/kernel/process.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/process.c,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 process.c --- arch/sh/kernel/process.c 15 Oct 2001 20:44:51 -0000 1.1.1.1 +++ arch/sh/kernel/process.c 28 Mar 2002 05:49:28 -0000 @@ -179,11 +179,7 @@ int dump_fpu(struct pt_regs *regs, elf_f fpvalid = tsk->used_math; if (fpvalid) { - unsigned long flags; - - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); } @@ -203,15 +199,9 @@ int copy_thread(int nr, unsigned long cl #if defined(__SH4__) struct task_struct *tsk = current; - if (tsk != &init_task) { - unsigned long flags; - - save_and_cli(flags); - unlazy_fpu(tsk); - restore_flags(flags); - p->thread.fpu = current->thread.fpu; - p->used_math = tsk->used_math; - } + unlazy_fpu(tsk); + 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; @@ -257,13 +247,7 @@ void dump_thread(struct pt_regs * regs, void __switch_to(struct task_struct *prev, struct task_struct *next) { #if defined(__SH4__) - if (prev != &init_task) { - unsigned long flags; - - save_and_cli(flags); - unlazy_fpu(prev); - restore_flags(flags); - } + unlazy_fpu(prev); #endif /* * Restore the kernel mode register Index: arch/sh/kernel/setup.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/setup.c,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 setup.c --- arch/sh/kernel/setup.c 30 Nov 2001 23:03:33 -0000 1.1.1.1.2.1 +++ arch/sh/kernel/setup.c 28 Mar 2002 05:49:28 -0000 @@ -485,9 +485,8 @@ void __init setup_arch(char **cmdline_p) } #if defined(__SH4__) - /* We already grab/initialized FPU in head.S. Make it consisitent. */ - init_task.used_math = 1; - init_task.flags |= PF_USEDFPU; + init_task.used_math = 0; + init_task.flags &= ~PF_USEDFPU; #endif paging_init(); } Index: arch/sh/kernel/signal.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/signal.c,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 signal.c --- arch/sh/kernel/signal.c 15 Oct 2001 20:44:52 -0000 1.1.1.1 +++ arch/sh/kernel/signal.c 28 Mar 2002 05:49:28 -0000 @@ -196,27 +196,20 @@ static inline int restore_sigcontext_fpu static inline int save_sigcontext_fpu(struct sigcontext *sc) { struct task_struct *tsk = current; - unsigned long flags; - int val; if (!tsk->used_math) { - val = 0; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(0, &sc->sc_ownedfp); return 0; } - val = 1; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(1, &sc->sc_ownedfp); /* This will cause a "finit" to be triggered by the next attempted FPU operation by the 'current' process. */ tsk->used_math = 0; - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); - return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, sizeof(long)*(16*2+2)); } @@ -255,7 +248,7 @@ restore_sigcontext(struct pt_regs *regs, } #endif - regs->syscall_nr = -1; /* disable syscall checks */ + regs->tra = -1; /* disable syscall checks */ err |= __get_user(*r0_p, &sc->sc_regs[0]); return err; } @@ -524,7 +517,7 @@ handle_signal(unsigned long sig, struct siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { /* Are we from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->tra >= 0) { /* If so, check system call restarting.. */ switch (regs->regs[0]) { case -ERESTARTNOHAND: @@ -538,7 +531,6 @@ handle_signal(unsigned long sig, struct } /* fallthrough */ case -ERESTARTNOINTR: - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } @@ -685,12 +677,11 @@ int do_signal(struct pt_regs *regs, sigs } /* Did we come from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->tra >= 0) { /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/time.c,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 time.c --- arch/sh/kernel/time.c 15 Oct 2001 20:44:50 -0000 1.1.1.1 +++ arch/sh/kernel/time.c 28 Mar 2002 05:49:28 -0000 @@ -176,6 +176,25 @@ void do_settimeofday(struct timeval *tv) /* last time the RTC clock got updated */ static long last_rtc_update; +static __inline__ void sh_do_profile (unsigned long pc) +{ + extern int _stext; + + if (!prof_buffer) + return; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Don't ignore out-of-bounds PC values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len-1) + pc = prof_len-1; + prof_buffer[pc]++; +} + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick Index: arch/sh/mm/Makefile =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/Makefile,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 Makefile --- arch/sh/mm/Makefile 15 Oct 2001 20:44:53 -0000 1.1.1.1 +++ arch/sh/mm/Makefile 28 Mar 2002 05:49:28 -0000 @@ -11,7 +11,7 @@ O_TARGET := mm.o obj-y := init.o fault.o extable.o clear_page.o copy_page.o obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o +obj-$(CONFIG_CPU_SH4) += cache-sh4.o ioremap.o USE_STANDARD_AS_RULE := true Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.1.1.1.2.3 diff -u -3 -p -r1.1.1.1.2.3 cache-sh4.c --- arch/sh/mm/cache-sh4.c 22 Mar 2002 14:02:09 -0000 1.1.1.1.2.3 +++ arch/sh/mm/cache-sh4.c 28 Mar 2002 05:49:28 -0000 @@ -1,9 +1,8 @@ /* $Id: cache-sh4.c,v 1.1.1.1.2.3 2002/03/22 14:02:09 gniibe Exp $ * - * linux/arch/sh/mm/cache.c + * linux/arch/sh/mm/cache-sh4.c * - * Copyright (C) 1999, 2000 Niibe Yutaka - * Copyright (C) 2001, 2002 Paul Mundt + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka */ #include <linux/config.h> @@ -208,55 +207,34 @@ void flush_cache_sigtramp(unsigned long restore_flags(flags); } -/* - * Writeback&Invalidate the D-cache of the page - */ -static void __flush_dcache_page(unsigned long phys) -{ - unsigned long addr, data; - unsigned long flags; - - phys |= CACHE_VALID; - - save_and_cli(flags); - jump_to_P2(); - - /* Loop all the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY; - addr < (CACHE_OC_ADDRESS_ARRAY - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - - back_to_P1(); - restore_flags(flags); -} - -static void __flush_icache_page(unsigned long phys) +static inline void flush_cache_4096(unsigned long start, + unsigned long phys) { +#if defined(CONFIG_CPU_SUBTYPE_SH7750) + register unsigned long addr __asm__ ("r4"); + register unsigned long data __asm__ ("r0"); + register unsigned long __r5 __asm__ ("r5") = phys; + register unsigned long __r6 __asm__ ("r6") = (0x1ffff000|CACHE_VALID); + register unsigned long __r7 __asm__ ("r7") = 0; + extern void __flush_cache_4096(unsigned long, unsigned long); + + asm volatile("jsr @%1; nop" + : "=r" (addr), "=r" (data) + : "0" (start), "1" (__flush_cache_4096 + 0x20000000), + "r" (__r5), "r" (__r6), "r" (__r7) + : "pr"); +#else + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ unsigned long addr, data; - unsigned long flags; - - phys |= CACHE_VALID; - - save_and_cli(flags); - jump_to_P2(); - - /* Loop all the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY; - addr < (CACHE_IC_ADDRESS_ARRAY - +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { + for (addr = start; addr < start + 4096; addr += 32) { data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); if (data == phys) ctrl_outl(0, addr); } - - back_to_P1(); - restore_flags(flags); +#endif } /* @@ -265,8 +243,22 @@ static void __flush_icache_page(unsigned */ void flush_dcache_page(struct page *page) { - if (test_bit(PG_mapped, &page->flags)) - __flush_dcache_page(PHYSADDR(page_address(page))); + if (test_bit(PG_mapped, &page->flags)) { + unsigned long phys = PHYSADDR(page_address(page)); + unsigned long flags; + + phys |= CACHE_VALID; + + save_and_cli(flags); + + /* Loop all the D-cache */ + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys); + + restore_flags(flags); + } } void flush_cache_all(void) @@ -298,15 +290,43 @@ void flush_cache_mm(struct mm_struct *mm * FIXME: Really, the optimal solution here would be able to flush out * individual lines created by the specified context, but this isn't * feasible for a number of architectures (such as MIPS, and some - * SPARC) .. is this possible for SuperH? (This is a non-issue if the - * SH4 cache is configured in write-through mode). + * SPARC) .. is this possible for SuperH? * - * In the meantime, we'll just flush all of the caches if we have a - * valid mm context.. this seems to be the simplest way to avoid at - * least a few wasted cache flushes. -Lethal + * In the meantime, we'll just flush all of the caches.. this + * seems to be the simplest way to avoid at least a few wasted + * cache flushes. -Lethal */ - if (mm->context != 0) - flush_cache_all(); + flush_cache_all(); +} + +static void __flush_cache_page(struct vm_area_struct *vma, + unsigned long address, + unsigned long phys) +{ + unsigned long flags; + + phys |= CACHE_VALID; + save_and_cli(flags); + + /* We only need to flush D-cache when we have alias */ + if ((address^phys) & CACHE_ALIAS) { + /* Loop 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), + phys); + /* Loop another 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), + phys); + } + + if (vma->vm_flags & VM_EXEC) + /* Loop 4K (half) of the I-cache */ + flush_cache_4096( + CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), + phys); + + restore_flags(flags); } /* @@ -321,39 +341,15 @@ 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; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; - - if (!find_vma(mm, start)) - return; - if (mm->context != current->active_mm->context) { - flush_cache_all(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - save_and_cli(flags); - jump_to_P2(); - - for (start; start < end; start += PAGE_SIZE) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if (pte_val(*pte) & _PAGE_PRESENT) { - __flush_icache_page(start); - __flush_dcache_page(start); - } - } - - back_to_P1(); - restore_flags(flags); - } + /* + * We could call flush_cache_page for the pages of these + * range, but it's really time consuming (we have to scan the + * caches all the time...). + * + * We can't use A-bit magic, as there's the case we don't have + * valid entry on TLB. + */ + flush_cache_all(); } /* @@ -367,8 +363,7 @@ void flush_cache_page(struct vm_area_str pmd_t *pmd; pte_t *pte; pte_t entry; - unsigned long phys, addr, data; - unsigned long flags; + unsigned long phys; dir = pgd_offset(vma->vm_mm, address); pmd = pmd_offset(dir, address); @@ -376,49 +371,11 @@ void flush_cache_page(struct vm_area_str return; pte = pte_offset(pmd, address); entry = *pte; - if (pte_none(entry) || !pte_present(entry)) + if (!(pte_val(entry) & _PAGE_PRESENT)) return; phys = pte_val(entry)&PTE_PHYS_MASK; - - phys |= CACHE_VALID; - save_and_cli(flags); - jump_to_P2(); - - /* We only need to flush D-cache when we have alias */ - if ((address^phys) & CACHE_ALIAS) { - /* Loop 4K of the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS); - addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) - +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - /* Loop another 4K of the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS); - addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) - +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - } - - if (vma->vm_flags & VM_EXEC) - /* Loop 4K of the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000); - addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000)) - +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - back_to_P1(); - restore_flags(flags); + __flush_cache_page(vma, address, phys); } /* Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 clear_page.S --- arch/sh/mm/clear_page.S 15 Oct 2001 20:44:53 -0000 1.1.1.1 +++ arch/sh/mm/clear_page.S 28 Mar 2002 05:49:28 -0000 @@ -1,10 +1,13 @@ /* $Id: clear_page.S,v 1.1.1.1 2001/10/15 20:44:53 mrbrown Exp $ * - * clear_page implementation of SuperH + * __clear_user_page, __clear_user, clear_page implementation of SuperH * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2001 Kaz Kojima + * Copyright (C) 2001, 2002 Niibe Yutaka * */ +#include <linux/config.h> +#include <linux/linkage.h> /* * clear_page @@ -18,7 +21,6 @@ * r4 --- to * r5 --- to + 4096 */ -#include <linux/linkage.h> ENTRY(clear_page) mov r4,r5 mov.w .Llimit,r0 @@ -50,3 +52,154 @@ ENTRY(clear_page) rts nop .Llimit: .word (4096-28) + +ENTRY(__clear_user) + ! + mov #0, r0 + mov #0xe0, r1 ! 0xffffffe0 + ! + ! r4..r4&~32 -------- not aligned [ Area 0 ] + ! r4&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] + ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] + ! + ! Clear area 0 + mov r4, r2 + and r1, r2 + cmp/eq r4, r2 + bt/s area1 + mov r4, r3 + sub r2, r3 + mov r4, r2 + ! +l0: dt r3 +0: mov.b r0, @r2 + bf/s l0 + add #1, r2 + ! + mov r4, r3 + add r5, r3 + and r1, r3 + ! + ! Clear area 1 +area1: +#if defined(__SH4__) +1: movca.l r0, @r2 +#else +1: mov.l r0, @r2 +#endif + add #4, r2 +2: mov.l r0, @r2 + add #4, r2 +3: mov.l r0, @r2 + add #4, r2 +4: mov.l r0, @r2 + add #4, r2 +5: mov.l r0, @r2 + add #4, r2 +6: mov.l r0, @r2 + add #4, r2 +7: mov.l r0, @r2 + add #4, r2 +8: mov.l r0, @r2 + add #4, r2 + cmp/hi r2, r3 + bt/s 1b + nop + ! + ! Clear area 2 + add r5, r4 + cmp/eq r4, r2 + bt/s done + sub r2, r4 +l2: dt r4 +9: mov.b r0, @r2 + bf/s l2 + add #1, r2 + ! +done: rts + nop ! return 0 as normal return + + ! return the number of bytes remained +bad_clear_user: + mov r4, r0 + mov r5, r0 + rts + sub r2, r0 + +.section __ex_table,"a" + .align 2 + .long 0b, bad_clear_user + .long 1b, bad_clear_user + .long 2b, bad_clear_user + .long 3b, bad_clear_user + .long 4b, bad_clear_user + .long 5b, bad_clear_user + .long 6b, bad_clear_user + .long 7b, bad_clear_user + .long 8b, bad_clear_user + .long 9b, bad_clear_user +.previous + +#if defined(__SH4__) +/* + * __clear_user_page + * @to: P1 address (with same color) + * @orig_to: P1 address + * + * void __clear_user_page(void *to, void *orig_to) + */ + +/* + * r0 --- scratch + * r4 --- to + * r5 --- orig_to + * r6 --- to + 4096 + */ +ENTRY(__clear_user_page) + mov.w .L4096,r0 + mov r4,r6 + add r0,r6 + mov #0,r0 + ! +1: ocbi @r5 + add #32,r5 + movca.l r0,@r4 + mov r4,r1 + add #32,r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + add #28,r4 + cmp/eq r6,r4 + bf/s 1b + ocbwb @r1 + ! + rts + nop +.L4096: .word 4096 + +#if defined(CONFIG_CPU_SUBTYPE_SH7750) +ENTRY(__flush_cache_4096) + .rept 128 + mov.l @r4,r0 + and r6,r0 + cmp/eq r5,r0 + bf 1f + mov.l r7,@r4 +1: add #32,r4 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop +#endif +#endif Index: arch/sh/mm/copy_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/copy_page.S,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 copy_page.S --- arch/sh/mm/copy_page.S 15 Oct 2001 20:44:53 -0000 1.1.1.1 +++ arch/sh/mm/copy_page.S 28 Mar 2002 05:49:28 -0000 @@ -1,10 +1,11 @@ /* $Id: copy_page.S,v 1.1.1.1 2001/10/15 20:44:53 mrbrown Exp $ * - * copy_page implementation of SuperH + * copy_page, __copy_user_page implementation of SuperH * * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima * */ +#include <linux/linkage.h> /* * copy_page @@ -21,7 +22,6 @@ * r10 --- to * r11 --- from */ -#include <linux/linkage.h> ENTRY(copy_page) mov.l r8,@-r15 mov.l r10,@-r15 @@ -66,4 +66,67 @@ ENTRY(copy_page) mov.l @r15+,r8 rts nop + +#if defined(__SH4__) +/* + * __copy_user_page + * @to: P1 address (with same color) + * @from: P1 address + * @orig_to: P1 address + * + * void __copy_user_page(void *to, void *from, void *orig_to) + */ + +/* + * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch + * r8 --- from + 4096 + * r9 --- orig_to + * r10 --- to + * r11 --- from + */ +#include <linux/linkage.h> +ENTRY(__copy_user_page) + mov.l r8,@-r15 + mov.l r9,@-r15 + mov.l r10,@-r15 + mov.l r11,@-r15 + mov r4,r10 + mov r5,r11 + mov r6,r9 + mov r5,r8 + mov.w .L4096,r0 + add r0,r8 + ! +1: ocbi @r9 + add #32,r9 + mov.l @r11+,r0 + mov.l @r11+,r1 + mov.l @r11+,r2 + mov.l @r11+,r3 + mov.l @r11+,r4 + mov.l @r11+,r5 + mov.l @r11+,r6 + mov.l @r11+,r7 + movca.l r0,@r10 + mov r10,r0 + add #32,r10 + mov.l r7,@-r10 + mov.l r6,@-r10 + mov.l r5,@-r10 + mov.l r4,@-r10 + mov.l r3,@-r10 + mov.l r2,@-r10 + mov.l r1,@-r10 + ocbwb @r0 + cmp/eq r11,r8 + bf/s 1b + add #28,r10 + ! + mov.l @r15+,r11 + mov.l @r15+,r10 + mov.l @r15+,r9 + mov.l @r15+,r8 + rts + nop +#endif .L4096: .word 4096 Index: include/asm-sh/hw_irq.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/hw_irq.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 hw_irq.h --- include/asm-sh/hw_irq.h 15 Oct 2001 20:45:08 -0000 1.1.1.1 +++ include/asm-sh/hw_irq.h 28 Mar 2002 05:49:28 -0000 @@ -1,6 +1,4 @@ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H -static __inline__ void sh_do_profile (unsigned long pc) {/*Not implemented yet*/} - static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ } #endif /* __ASM_SH_HW_IRQ_H */ Index: include/asm-sh/mmu_context.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/mmu_context.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 mmu_context.h --- include/asm-sh/mmu_context.h 15 Oct 2001 20:45:10 -0000 1.1.1.1 +++ include/asm-sh/mmu_context.h 28 Mar 2002 05:49:28 -0000 @@ -29,19 +29,32 @@ extern unsigned long mmu_context_cache; */ #define MMU_VPN_MASK 0xfffff000 +/* + * Get MMU context if needed. + */ static __inline__ void -get_new_mmu_context(struct mm_struct *mm) +get_mmu_context(struct mm_struct *mm) { extern void flush_tlb_all(void); + unsigned long mc = mmu_context_cache; - unsigned long mc = ++mmu_context_cache; + /* Check if we have old version of context. */ + if (((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0) + /* It's up to date, do nothing */ + return; + /* It's old, we need to get new context with new version. */ + mc = ++mmu_context_cache; if (!(mc & MMU_CONTEXT_ASID_MASK)) { - /* We exhaust ASID of this version. - Flush all TLB and start new cycle. */ + /* + * We exhaust ASID of this version. + * Flush all TLB and start new cycle. + */ flush_tlb_all(); - /* Fix version if needed. - Note that we avoid version #0 to distingush NO_CONTEXT. */ + /* + * Fix version; Note that we avoid version #0 + * to distingush NO_CONTEXT. + */ if (!mc) mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION; } @@ -49,21 +62,6 @@ get_new_mmu_context(struct mm_struct *mm } /* - * Get MMU context if needed. - */ -static __inline__ void -get_mmu_context(struct mm_struct *mm) -{ - if (mm) { - unsigned long mc = mmu_context_cache; - /* Check if we have old version of context. - If it's old, we need to get new context with new version. */ - if ((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) - get_new_mmu_context(mm); - } -} - -/* * Initialize the context related info for a new mm_struct * instance. */ @@ -169,8 +167,6 @@ static __inline__ void switch_mm(struct if (prev != next) { unsigned long __pgdir = (unsigned long)next->pgd; - clear_bit(cpu, &prev->cpu_vm_mask); - set_bit(cpu, &next->cpu_vm_mask); __asm__ __volatile__("mov.l %0, %1" : /* no output */ : "r" (__pgdir), "m" (__m(MMU_TTB))); @@ -185,4 +181,5 @@ static __inline__ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } + #endif /* __ASM_SH_MMU_CONTEXT_H */ Index: include/asm-sh/ptrace.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/ptrace.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 ptrace.h --- include/asm-sh/ptrace.h 15 Oct 2001 20:45:11 -0000 1.1.1.1 +++ include/asm-sh/ptrace.h 28 Mar 2002 05:49:28 -0000 @@ -61,7 +61,7 @@ struct pt_regs { unsigned long gbr; unsigned long mach; unsigned long macl; - long syscall_nr; + long tra; }; #ifdef __KERNEL__ Index: include/asm-sh/uaccess.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/uaccess.h,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 uaccess.h --- include/asm-sh/uaccess.h 3 Nov 2001 00:52:47 -0000 1.1.1.1.2.1 +++ include/asm-sh/uaccess.h 28 Mar 2002 05:49:28 -0000 @@ -308,39 +308,11 @@ __copy_res; }) __copy_user((void *)(to), \ (void *)(from), n) -/* XXX: Not sure it works well.. - should be such that: 4byte clear and the rest. */ -static __inline__ __kernel_size_t -__clear_user(void *addr, __kernel_size_t size) -{ - unsigned long __a; - - __asm__ __volatile__( - "9:\n\t" - "dt %0\n" - "1:\n\t" - "mov.b %4, @%1\n\t" - "bf/s 9b\n\t" - " add #1, %1\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\n\t" - "mov.l 4f, %1\n\t" - "jmp @%1\n\t" - " nop\n" - ".balign 4\n" - "4: .long 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .balign 4\n" - " .long 1b,3b\n" - ".previous" - : "=r" (size), "=r" (__a) - : "0" (size), "1" (addr), "r" (0) - : "memory", "t"); - - return size; -} +/* + * Clear the area and return remaining number of bytes + * (on failure. Usually it's 0.) + */ +extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); #define clear_user(addr,n) ({ \ void * __cl_addr = (addr); \ @@ -396,8 +368,6 @@ if(__access_ok(__sfu_src, __sfu_count)) __sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \ } __sfu_res; }) -#define strlen_user(str) strnlen_user(str, ~0UL >> 1) - /* * Return the size of a string (including the ending 0!) */ @@ -436,10 +406,18 @@ static __inline__ long __strnlen_user(co static __inline__ long strnlen_user(const char *s, long n) { - if (!__addr_ok(s)) + if (!access_ok(VERIFY_READ, s, n)) return 0; else return __strnlen_user(s, n); +} + +static __inline__ long strlen_user(const char *s) +{ + if (!access_ok(VERIFY_READ, s, 0)) + return 0; + else + return __strnlen_user(s, ~0UL >> 1); } struct exception_table_entry |
From: NIIBE Y. <gn...@m1...> - 2002-03-28 02:17:09
|
NIIBE Yutaka wrote: > The change I've made works well for 7750 (in P2). With instruction > cache enabled (P1), I think that loop works better. I mean things like this. 2002-03-28 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/clear_page.S (__flush_cache_4096): Only define for SH7750. * arch/sh/mm/cache-sh4.c (flush_cache_4096): Plain loop for SH7751 and ST40 (no need to go P2). Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/cache-sh4.c,v retrieving revision 1.8 diff -u -3 -p -r1.8 cache-sh4.c --- arch/sh/mm/cache-sh4.c 27 Mar 2002 09:30:48 -0000 1.8 +++ arch/sh/mm/cache-sh4.c 28 Mar 2002 02:14:09 -0000 @@ -211,6 +211,7 @@ void flush_cache_sigtramp(unsigned long static inline void flush_cache_4096(unsigned long start, unsigned long phys) { +#if defined(CONFIG_CPU_SUBTYPE_SH7750) register unsigned long addr __asm__ ("r4"); register unsigned long data __asm__ ("r0"); register unsigned long __r5 __asm__ ("r5") = phys; @@ -223,6 +224,18 @@ static inline void flush_cache_4096(unsi : "0" (start), "1" (__flush_cache_4096 + 0x20000000), "r" (__r5), "r" (__r6), "r" (__r7) : "pr"); +#else + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + unsigned long addr, data; + for (addr = start; addr < start + 4096; addr += 32) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } +#endif } /* Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/mm/clear_page.S,v retrieving revision 1.2 diff -u -3 -p -r1.2 clear_page.S --- arch/sh/mm/clear_page.S 27 Mar 2002 09:30:48 -0000 1.2 +++ arch/sh/mm/clear_page.S 28 Mar 2002 02:14:09 -0000 @@ -180,14 +180,7 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -/************* - unsigned long addr, data; - for (addr = start; addr < start + 4096; addr += 32) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } -*************/ +#if defined(CONFIG_CPU_SUBTYPE_SH7750) ENTRY(__flush_cache_4096) .rept 128 mov.l @r4,r0 @@ -206,4 +199,5 @@ ENTRY(__flush_cache_4096) nop rts nop +#endif #endif |
From: NIIBE Y. <gn...@m1...> - 2002-03-27 23:54:06
|
David McKay wrote: > Niibe-san, > One of the differences between the 7750 and 7751 (and ST40) processors > is that the restriction to flush D-cache from P2 only has been lifted. Excellent! I didn't know that. If I could suggest more feature, I think it would be great that if we had a feature of flushing cache of physcal address (page), so that we don't need to loop all the cache, in the first place. The change I've made works well for 7750 (in P2). With instruction cache enabled (P1), I think that loop works better. -- |
From: NIIBE Y. <gn...@m1...> - 2002-03-27 23:46:52
|
M. R. Brown wrote: > Wow ... were you planning on merging these with linux-2_4-branch also? Yes. Besides this, we have important bug fixes (FPU thing, syscall restart) and feature (kernel profiling support), which should be merged into 2.4. > For this and your other changes, do you have numbers to show your > improvements? We need more information, that's the reason I've implemented kernel profiling (at last ;-). I have only rough one. I do: $ time for x in 0 1 2 3 4 5 6 7 8 9; do fo y in 0 1 2 3 4 5 6 7 8 9; \ do sh -c "echo >/dev/null"; done; done to see how exec/exit goes. flush_cache_range was the bad guy which heavily calls flush_cache_4096 or __flush_cache_page. It took about 4sec user, 25sec system with old implementation, while 4sec user, 17sec system with new implementation. It is because of number of instructions spent for cache flushing. On SolutionEngine 7750. BTW, when we change flush_cache_range to just call flush_cache_all, it goes 4sec user and 4sec system. It seems for me that we have no way other than flush_cache_all... -- |