aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-07 13:08:33 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-07 13:08:33 -0500
commitd694c16bc332c7e706f44e3d10bea06228166a6f (patch)
tree72d0ab61ce633002a1c4de2406101e28e101afa3 /arch
parentd04f41e35343f1d788551fd3f753f51794f4afcf (diff)
parentccd45ad405bcb1504bd923bd0487902374c942c8 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: sh: Kill off I/O cruft for R7780RP. sh: Revert lazy dcache writeback changes. sh: Enable SM501 support for RTS7751R2D. sh: Use L1_CACHE_BYTES for .data.cacheline_aligned. sysctl: Support vdso_enabled sysctl on SH. sh: Fix kernel thread stack corruption with preempt. doc: Add SH to vdso and earlyprintk in kernel-parameters.txt sh: Fix sigmask trampling in signal delivery. sh: Clear UBC when not in use.
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile2
-rw-r--r--arch/sh/boards/renesas/r7780rp/io.c233
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c24
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c26
-rw-r--r--arch/sh/configs/rts7751r2d_defconfig110
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/io_generic.c3
-rw-r--r--arch/sh/kernel/process.c5
-rw-r--r--arch/sh/kernel/ptrace.c45
-rw-r--r--arch/sh/kernel/signal.c4
-rw-r--r--arch/sh/kernel/vmlinux.lds.S3
-rw-r--r--arch/sh/mm/cache-sh4.c12
-rw-r--r--arch/sh/mm/cache-sh7705.c9
-rw-r--r--arch/sh/mm/pg-sh4.c22
-rw-r--r--arch/sh/mm/pg-sh7705.c31
-rw-r--r--arch/sh/mm/tlb-flush.c55
-rw-r--r--arch/sh/mm/tlb-sh3.c63
-rw-r--r--arch/sh/mm/tlb-sh4.c68
18 files changed, 353 insertions, 364 deletions
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 3c93012e91a3..ed5f5a9a3b3e 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the R7780RP-1 specific parts of the kernel 2# Makefile for the R7780RP-1 specific parts of the kernel
3# 3#
4 4
5obj-y := setup.o io.o irq.o 5obj-y := setup.o irq.o
6 6
7obj-$(CONFIG_PUSH_SWITCH) += psw.o 7obj-$(CONFIG_PUSH_SWITCH) += psw.o
diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c
deleted file mode 100644
index f74d2ffb3851..000000000000
--- a/arch/sh/boards/renesas/r7780rp/io.c
+++ /dev/null
@@ -1,233 +0,0 @@
1/*
2 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
3 * Based largely on io_se.c.
4 *
5 * I/O routine for Renesas Solutions Highlander R7780RP-1
6 *
7 * Initial version only to support LAN access; some
8 * placeholder code from io_r7780rp.c left in with the
9 * expectation of later SuperIO and PCMCIA access.
10 */
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/io.h>
15#include <asm/r7780rp.h>
16#include <asm/addrspace.h>
17
18static inline unsigned long port88796l(unsigned int port, int flag)
19{
20 unsigned long addr;
21
22 if (flag)
23 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
24 else
25 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
26
27 return addr;
28}
29
30#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
31#define CHECK_AX88796L_PORT(port) \
32 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
33#else
34#define CHECK_AX88796L_PORT(port) (0)
35#endif
36
37/*
38 * General outline: remap really low stuff [eventually] to SuperIO,
39 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
40 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
41 * should be way beyond the window, and is used w/o translation for
42 * compatibility.
43 */
44u8 r7780rp_inb(unsigned long port)
45{
46 if (CHECK_AX88796L_PORT(port))
47 return ctrl_inw(port88796l(port, 0)) & 0xff;
48 else if (is_pci_ioaddr(port))
49 return ctrl_inb(pci_ioaddr(port));
50
51 return ctrl_inw(port) & 0xff;
52}
53
54u8 r7780rp_inb_p(unsigned long port)
55{
56 u8 v;
57
58 if (CHECK_AX88796L_PORT(port))
59 v = ctrl_inw(port88796l(port, 0)) & 0xff;
60 else if (is_pci_ioaddr(port))
61 v = ctrl_inb(pci_ioaddr(port));
62 else
63 v = ctrl_inw(port) & 0xff;
64
65 ctrl_delay();
66
67 return v;
68}
69
70u16 r7780rp_inw(unsigned long port)
71{
72 if (is_pci_ioaddr(port))
73 return ctrl_inw(pci_ioaddr(port));
74
75 return ctrl_inw(port);
76}
77
78u32 r7780rp_inl(unsigned long port)
79{
80 if (is_pci_ioaddr(port))
81 return ctrl_inl(pci_ioaddr(port));
82
83 return ctrl_inl(port);
84}
85
86void r7780rp_outb(u8 value, unsigned long port)
87{
88 if (CHECK_AX88796L_PORT(port))
89 ctrl_outw(value, port88796l(port, 0));
90 else if (is_pci_ioaddr(port))
91 ctrl_outb(value, pci_ioaddr(port));
92 else
93 ctrl_outb(value, port);
94}
95
96void r7780rp_outb_p(u8 value, unsigned long port)
97{
98 if (CHECK_AX88796L_PORT(port))
99 ctrl_outw(value, port88796l(port, 0));
100 else if (is_pci_ioaddr(port))
101 ctrl_outb(value, pci_ioaddr(port));
102 else
103 ctrl_outb(value, port);
104
105 ctrl_delay();
106}
107
108void r7780rp_outw(u16 value, unsigned long port)
109{
110 if (is_pci_ioaddr(port))
111 ctrl_outw(value, pci_ioaddr(port));
112 else
113 ctrl_outw(value, port);
114}
115
116void r7780rp_outl(u32 value, unsigned long port)
117{
118 if (is_pci_ioaddr(port))
119 ctrl_outl(value, pci_ioaddr(port));
120 else
121 ctrl_outl(value, port);
122}
123
124void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
125{
126 volatile u16 *p;
127 u8 *buf = dst;
128
129 if (CHECK_AX88796L_PORT(port)) {
130 p = (volatile u16 *)port88796l(port, 0);
131 while (count--)
132 *buf++ = *p & 0xff;
133 } else if (is_pci_ioaddr(port)) {
134 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
135
136 while (count--)
137 *buf++ = *bp;
138 } else {
139 p = (volatile u16 *)port;
140 while (count--)
141 *buf++ = *p & 0xff;
142 }
143}
144
145void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
146{
147 volatile u16 *p;
148 u16 *buf = dst;
149
150 if (CHECK_AX88796L_PORT(port))
151 p = (volatile u16 *)port88796l(port, 1);
152 else if (is_pci_ioaddr(port))
153 p = (volatile u16 *)pci_ioaddr(port);
154 else
155 p = (volatile u16 *)port;
156
157 while (count--)
158 *buf++ = *p;
159
160 flush_dcache_all();
161}
162
163void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
164{
165 if (is_pci_ioaddr(port)) {
166 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
167 u32 *buf = dst;
168
169 while (count--)
170 *buf++ = *p;
171 }
172}
173
174void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
175{
176 volatile u16 *p;
177 const u8 *buf = src;
178
179 if (CHECK_AX88796L_PORT(port)) {
180 p = (volatile u16 *)port88796l(port, 0);
181 while (count--)
182 *p = *buf++;
183 } else if (is_pci_ioaddr(port)) {
184 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
185
186 while (count--)
187 *bp = *buf++;
188 } else
189 while (count--)
190 ctrl_outb(*buf++, port);
191}
192
193void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
194{
195 volatile u16 *p;
196 const u16 *buf = src;
197
198 if (CHECK_AX88796L_PORT(port))
199 p = (volatile u16 *)port88796l(port, 1);
200 else if (is_pci_ioaddr(port))
201 p = (volatile u16 *)pci_ioaddr(port);
202 else
203 p = (volatile u16 *)port;
204
205 while (count--)
206 *p = *buf++;
207
208 flush_dcache_all();
209}
210
211void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
212{
213 const u32 *buf = src;
214 u32 *p;
215
216 if (is_pci_ioaddr(port))
217 p = (u32 *)pci_ioaddr(port);
218 else
219 p = (u32 *)port;
220
221 while (count--)
222 ctrl_outl(*buf++, (unsigned long)p);
223}
224
225void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
226{
227 if (CHECK_AX88796L_PORT(port))
228 return (void __iomem *)port88796l(port, size > 1);
229 else if (is_pci_ioaddr(port))
230 return (void __iomem *)pci_ioaddr(port);
231
232 return (void __iomem *)port;
233}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 0d74db9f1792..2faba6679e64 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -187,31 +187,7 @@ static void __init r7780rp_setup(char **cmdline_p)
187struct sh_machine_vector mv_r7780rp __initmv = { 187struct sh_machine_vector mv_r7780rp __initmv = {
188 .mv_name = "Highlander R7780RP-1", 188 .mv_name = "Highlander R7780RP-1",
189 .mv_setup = r7780rp_setup, 189 .mv_setup = r7780rp_setup,
190
191 .mv_nr_irqs = 109, 190 .mv_nr_irqs = 109,
192
193 .mv_inb = r7780rp_inb,
194 .mv_inw = r7780rp_inw,
195 .mv_inl = r7780rp_inl,
196 .mv_outb = r7780rp_outb,
197 .mv_outw = r7780rp_outw,
198 .mv_outl = r7780rp_outl,
199
200 .mv_inb_p = r7780rp_inb_p,
201 .mv_inw_p = r7780rp_inw,
202 .mv_inl_p = r7780rp_inl,
203 .mv_outb_p = r7780rp_outb_p,
204 .mv_outw_p = r7780rp_outw,
205 .mv_outl_p = r7780rp_outl,
206
207 .mv_insb = r7780rp_insb,
208 .mv_insw = r7780rp_insw,
209 .mv_insl = r7780rp_insl,
210 .mv_outsb = r7780rp_outsb,
211 .mv_outsw = r7780rp_outsw,
212 .mv_outsl = r7780rp_outsl,
213
214 .mv_ioport_map = r7780rp_ioport_map,
215 .mv_init_irq = init_r7780rp_IRQ, 191 .mv_init_irq = init_r7780rp_IRQ,
216}; 192};
217ALIAS_MV(r7780rp) 193ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 44b42082a0af..593f26a85e9c 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -12,6 +12,7 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/pata_platform.h> 13#include <linux/pata_platform.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/sm501.h>
15#include <linux/pm.h> 16#include <linux/pm.h>
16#include <asm/machvec.h> 17#include <asm/machvec.h>
17#include <asm/rts7751r2d.h> 18#include <asm/rts7751r2d.h>
@@ -111,10 +112,35 @@ static struct platform_device heartbeat_device = {
111 .resource = heartbeat_resources, 112 .resource = heartbeat_resources,
112}; 113};
113 114
115static struct resource sm501_resources[] = {
116 [0] = {
117 .start = 0x10000000,
118 .end = 0x13e00000 - 1,
119 .flags = IORESOURCE_MEM,
120 },
121 [1] = {
122 .start = 0x13e00000,
123 .end = 0x13ffffff,
124 .flags = IORESOURCE_MEM,
125 },
126 [2] = {
127 .start = 32,
128 .flags = IORESOURCE_IRQ,
129 },
130};
131
132static struct platform_device sm501_device = {
133 .name = "sm501",
134 .id = -1,
135 .num_resources = ARRAY_SIZE(sm501_resources),
136 .resource = sm501_resources,
137};
138
114static struct platform_device *rts7751r2d_devices[] __initdata = { 139static struct platform_device *rts7751r2d_devices[] __initdata = {
115 &uart_device, 140 &uart_device,
116 &heartbeat_device, 141 &heartbeat_device,
117 &cf_ide_device, 142 &cf_ide_device,
143 &sm501_device,
118}; 144};
119 145
120static int __init rts7751r2d_devices_setup(void) 146static int __init rts7751r2d_devices_setup(void)
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index db6a02df5af6..a59bb78bd071 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,14 +1,13 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20 3# Linux kernel version: 2.6.21-rc1
4# Thu Feb 15 17:17:29 2007 4# Thu Mar 1 16:42:40 2007
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y 7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y 8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y 9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y 10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
12CONFIG_GENERIC_IRQ_PROBE=y 11CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y 12CONFIG_GENERIC_CALIBRATE_DELAY=y
14# CONFIG_GENERIC_TIME is not set 13# CONFIG_GENERIC_TIME is not set
@@ -33,6 +32,7 @@ CONFIG_LOCALVERSION_AUTO=y
33CONFIG_SWAP=y 32CONFIG_SWAP=y
34CONFIG_SYSVIPC=y 33CONFIG_SYSVIPC=y
35# CONFIG_IPC_NS is not set 34# CONFIG_IPC_NS is not set
35CONFIG_SYSVIPC_SYSCTL=y
36# CONFIG_POSIX_MQUEUE is not set 36# CONFIG_POSIX_MQUEUE is not set
37# CONFIG_BSD_PROCESS_ACCT is not set 37# CONFIG_BSD_PROCESS_ACCT is not set
38# CONFIG_TASKSTATS is not set 38# CONFIG_TASKSTATS is not set
@@ -119,7 +119,6 @@ CONFIG_SH_RTS7751R2D=y
119# CONFIG_SH_SHMIN is not set 119# CONFIG_SH_SHMIN is not set
120# CONFIG_SH_7206_SOLUTION_ENGINE is not set 120# CONFIG_SH_7206_SOLUTION_ENGINE is not set
121# CONFIG_SH_7619_SOLUTION_ENGINE is not set 121# CONFIG_SH_7619_SOLUTION_ENGINE is not set
122# CONFIG_SH_ASDAP310 is not set
123# CONFIG_SH_UNKNOWN is not set 122# CONFIG_SH_UNKNOWN is not set
124 123
125# 124#
@@ -281,7 +280,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000
281CONFIG_BOOT_LINK_OFFSET=0x00800000 280CONFIG_BOOT_LINK_OFFSET=0x00800000
282# CONFIG_UBC_WAKEUP is not set 281# CONFIG_UBC_WAKEUP is not set
283CONFIG_CMDLINE_BOOL=y 282CONFIG_CMDLINE_BOOL=y
284CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" 283CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1"
285 284
286# 285#
287# Bus options 286# Bus options
@@ -433,6 +432,7 @@ CONFIG_FW_LOADER=m
433# 432#
434# Plug and Play support 433# Plug and Play support
435# 434#
435# CONFIG_PNPACPI is not set
436 436
437# 437#
438# Block devices 438# Block devices
@@ -770,7 +770,26 @@ CONFIG_NET_WIRELESS=y
770# 770#
771# Input device support 771# Input device support
772# 772#
773# CONFIG_INPUT is not set 773CONFIG_INPUT=y
774# CONFIG_INPUT_FF_MEMLESS is not set
775
776#
777# Userland interfaces
778#
779# CONFIG_INPUT_MOUSEDEV is not set
780# CONFIG_INPUT_JOYDEV is not set
781# CONFIG_INPUT_TSDEV is not set
782# CONFIG_INPUT_EVDEV is not set
783# CONFIG_INPUT_EVBUG is not set
784
785#
786# Input Device Drivers
787#
788# CONFIG_INPUT_KEYBOARD is not set
789# CONFIG_INPUT_MOUSE is not set
790# CONFIG_INPUT_JOYSTICK is not set
791# CONFIG_INPUT_TOUCHSCREEN is not set
792# CONFIG_INPUT_MISC is not set
774 793
775# 794#
776# Hardware I/O ports 795# Hardware I/O ports
@@ -781,7 +800,10 @@ CONFIG_NET_WIRELESS=y
781# 800#
782# Character devices 801# Character devices
783# 802#
784# CONFIG_VT is not set 803CONFIG_VT=y
804CONFIG_VT_CONSOLE=y
805CONFIG_HW_CONSOLE=y
806CONFIG_VT_HW_CONSOLE_BINDING=y
785# CONFIG_SERIAL_NONSTANDARD is not set 807# CONFIG_SERIAL_NONSTANDARD is not set
786 808
787# 809#
@@ -857,6 +879,11 @@ CONFIG_HWMON=y
857# CONFIG_HWMON_DEBUG_CHIP is not set 879# CONFIG_HWMON_DEBUG_CHIP is not set
858 880
859# 881#
882# Multifunction device drivers
883#
884CONFIG_MFD_SM501=y
885
886#
860# Multimedia devices 887# Multimedia devices
861# 888#
862# CONFIG_VIDEO_DEV is not set 889# CONFIG_VIDEO_DEV is not set
@@ -869,9 +896,66 @@ CONFIG_HWMON=y
869# 896#
870# Graphics support 897# Graphics support
871# 898#
872CONFIG_FIRMWARE_EDID=y
873# CONFIG_FB is not set
874# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 899# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
900CONFIG_FB=y
901# CONFIG_FIRMWARE_EDID is not set
902# CONFIG_FB_DDC is not set
903CONFIG_FB_CFB_FILLRECT=y
904CONFIG_FB_CFB_COPYAREA=y
905CONFIG_FB_CFB_IMAGEBLIT=y
906# CONFIG_FB_SVGALIB is not set
907# CONFIG_FB_MACMODES is not set
908# CONFIG_FB_BACKLIGHT is not set
909# CONFIG_FB_MODE_HELPERS is not set
910# CONFIG_FB_TILEBLITTING is not set
911
912#
913# Frambuffer hardware drivers
914#
915# CONFIG_FB_CIRRUS is not set
916# CONFIG_FB_PM2 is not set
917# CONFIG_FB_CYBER2000 is not set
918# CONFIG_FB_ASILIANT is not set
919# CONFIG_FB_IMSTT is not set
920# CONFIG_FB_EPSON1355 is not set
921# CONFIG_FB_S1D13XXX is not set
922# CONFIG_FB_NVIDIA is not set
923# CONFIG_FB_RIVA is not set
924# CONFIG_FB_MATROX is not set
925# CONFIG_FB_RADEON is not set
926# CONFIG_FB_ATY128 is not set
927# CONFIG_FB_ATY is not set
928# CONFIG_FB_S3 is not set
929# CONFIG_FB_SAVAGE is not set
930# CONFIG_FB_SIS is not set
931# CONFIG_FB_NEOMAGIC is not set
932# CONFIG_FB_KYRO is not set
933# CONFIG_FB_3DFX is not set
934# CONFIG_FB_VOODOO1 is not set
935# CONFIG_FB_TRIDENT is not set
936CONFIG_FB_SM501=y
937# CONFIG_FB_VIRTUAL is not set
938
939#
940# Console display driver support
941#
942CONFIG_DUMMY_CONSOLE=y
943CONFIG_FRAMEBUFFER_CONSOLE=y
944# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
945# CONFIG_FONTS is not set
946CONFIG_FONT_8x8=y
947CONFIG_FONT_8x16=y
948
949#
950# Logo configuration
951#
952CONFIG_LOGO=y
953# CONFIG_LOGO_LINUX_MONO is not set
954# CONFIG_LOGO_LINUX_VGA16 is not set
955# CONFIG_LOGO_LINUX_CLUT224 is not set
956# CONFIG_LOGO_SUPERH_MONO is not set
957# CONFIG_LOGO_SUPERH_VGA16 is not set
958CONFIG_LOGO_SUPERH_CLUT224=y
875 959
876# 960#
877# Sound 961# Sound
@@ -985,6 +1069,12 @@ CONFIG_SOUND_PRIME=m
985CONFIG_AC97_BUS=m 1069CONFIG_AC97_BUS=m
986 1070
987# 1071#
1072# HID Devices
1073#
1074CONFIG_HID=y
1075# CONFIG_HID_DEBUG is not set
1076
1077#
988# USB support 1078# USB support
989# 1079#
990CONFIG_USB_ARCH_HAS_HCD=y 1080CONFIG_USB_ARCH_HAS_HCD=y
@@ -1237,7 +1327,7 @@ CONFIG_LOG_BUF_SHIFT=14
1237CONFIG_EARLY_SCIF_CONSOLE=y 1327CONFIG_EARLY_SCIF_CONSOLE=y
1238CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 1328CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
1239CONFIG_EARLY_PRINTK=y 1329CONFIG_EARLY_PRINTK=y
1240# CONFIG_KGDB is not set 1330# CONFIG_SH_KGDB is not set
1241 1331
1242# 1332#
1243# Security options 1333# Security options
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index ab4ebb856c2a..b46728027195 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -224,7 +224,7 @@ work_resched:
224syscall_exit_work: 224syscall_exit_work:
225 ! r0: current_thread_info->flags 225 ! r0: current_thread_info->flags
226 ! r8: current_thread_info 226 ! r8: current_thread_info
227 tst #_TIF_SYSCALL_TRACE, r0 227 tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0
228 bt/s work_pending 228 bt/s work_pending
229 tst #_TIF_NEED_RESCHED, r0 229 tst #_TIF_NEED_RESCHED, r0
230#ifdef CONFIG_TRACE_IRQFLAGS 230#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 66626c03e1ee..771ea4230441 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/machvec.h> 16#include <asm/machvec.h>
17#include <asm/cacheflush.h>
18 17
19#ifdef CONFIG_CPU_SH3 18#ifdef CONFIG_CPU_SH3
20/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a 19/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
@@ -96,7 +95,6 @@ void generic_insw(unsigned long port, void *dst, unsigned long count)
96 while (count--) 95 while (count--)
97 *buf++ = *port_addr; 96 *buf++ = *port_addr;
98 97
99 flush_dcache_all();
100 dummy_read(); 98 dummy_read();
101} 99}
102 100
@@ -171,7 +169,6 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count)
171 while (count--) 169 while (count--)
172 *port_addr = *buf++; 170 *port_addr = *buf++;
173 171
174 flush_dcache_all();
175 dummy_read(); 172 dummy_read();
176} 173}
177 174
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 9d6a438b3eaf..e7607366ac4e 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -250,12 +250,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
250 childregs->regs[15] = usp; 250 childregs->regs[15] = usp;
251 ti->addr_limit = USER_DS; 251 ti->addr_limit = USER_DS;
252 } else { 252 } else {
253 childregs->regs[15] = (unsigned long)task_stack_page(p) + 253 childregs->regs[15] = (unsigned long)childregs;
254 THREAD_SIZE;
255 ti->addr_limit = KERNEL_DS; 254 ti->addr_limit = KERNEL_DS;
256 } 255 }
257 256
258 if (clone_flags & CLONE_SETTLS) 257 if (clone_flags & CLONE_SETTLS)
259 childregs->gbr = childregs->regs[0]; 258 childregs->gbr = childregs->regs[0];
260 259
261 childregs->regs[0] = 0; /* Set return value for child */ 260 childregs->regs[0] = 0; /* Set return value for child */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 04ca13a041c1..855f7246cfff 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -8,7 +8,6 @@
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
9 * 9 *
10 */ 10 */
11
12#include <linux/kernel.h> 11#include <linux/kernel.h>
13#include <linux/sched.h> 12#include <linux/sched.h>
14#include <linux/mm.h> 13#include <linux/mm.h>
@@ -20,8 +19,7 @@
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/security.h> 20#include <linux/security.h>
22#include <linux/signal.h> 21#include <linux/signal.h>
23 22#include <linux/io.h>
24#include <asm/io.h>
25#include <asm/uaccess.h> 23#include <asm/uaccess.h>
26#include <asm/pgtable.h> 24#include <asm/pgtable.h>
27#include <asm/system.h> 25#include <asm/system.h>
@@ -59,6 +57,23 @@ static inline int put_stack_long(struct task_struct *task, int offset,
59 return 0; 57 return 0;
60} 58}
61 59
60static void ptrace_disable_singlestep(struct task_struct *child)
61{
62 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
63
64 /*
65 * Ensure the UBC is not programmed at the next context switch.
66 *
67 * Normally this is not needed but there are sequences such as
68 * singlestep, signal delivery, and continue that leave the
69 * ubc_pc non-zero leading to spurious SIGTRAPs.
70 */
71 if (child->thread.ubc_pc != 0) {
72 ubc_usercnt -= 1;
73 child->thread.ubc_pc = 0;
74 }
75}
76
62/* 77/*
63 * Called by kernel/ptrace.c when detaching.. 78 * Called by kernel/ptrace.c when detaching..
64 * 79 *
@@ -66,7 +81,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
66 */ 81 */
67void ptrace_disable(struct task_struct *child) 82void ptrace_disable(struct task_struct *child)
68{ 83{
69 /* nothing to do.. */ 84 ptrace_disable_singlestep(child);
70} 85}
71 86
72long arch_ptrace(struct task_struct *child, long request, long addr, long data) 87long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -76,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
76 91
77 switch (request) { 92 switch (request) {
78 /* when I and D space are separate, these will need to be fixed. */ 93 /* when I and D space are separate, these will need to be fixed. */
79 case PTRACE_PEEKTEXT: /* read word at location addr. */ 94 case PTRACE_PEEKTEXT: /* read word at location addr. */
80 case PTRACE_PEEKDATA: { 95 case PTRACE_PEEKDATA: {
81 unsigned long tmp; 96 unsigned long tmp;
82 int copied; 97 int copied;
@@ -94,7 +109,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
94 unsigned long tmp; 109 unsigned long tmp;
95 110
96 ret = -EIO; 111 ret = -EIO;
97 if ((addr & 3) || addr < 0 || 112 if ((addr & 3) || addr < 0 ||
98 addr > sizeof(struct user) - 3) 113 addr > sizeof(struct user) - 3)
99 break; 114 break;
100 115
@@ -129,7 +144,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
129 144
130 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 145 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
131 ret = -EIO; 146 ret = -EIO;
132 if ((addr & 3) || addr < 0 || 147 if ((addr & 3) || addr < 0 ||
133 addr > sizeof(struct user) - 3) 148 addr > sizeof(struct user) - 3)
134 break; 149 break;
135 150
@@ -156,6 +171,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
156 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 171 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
157 else 172 else
158 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 173 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
174
175 ptrace_disable_singlestep(child);
176
159 child->exit_code = data; 177 child->exit_code = data;
160 wake_up_process(child); 178 wake_up_process(child);
161 ret = 0; 179 ret = 0;
@@ -163,14 +181,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
163 } 181 }
164 182
165/* 183/*
166 * make the child exit. Best I can do is send it a sigkill. 184 * make the child exit. Best I can do is send it a sigkill.
167 * perhaps it should be put in the status that it wants to 185 * perhaps it should be put in the status that it wants to
168 * exit. 186 * exit.
169 */ 187 */
170 case PTRACE_KILL: { 188 case PTRACE_KILL: {
171 ret = 0; 189 ret = 0;
172 if (child->exit_state == EXIT_ZOMBIE) /* already dead */ 190 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
173 break; 191 break;
192 ptrace_disable_singlestep(child);
174 child->exit_code = SIGKILL; 193 child->exit_code = SIGKILL;
175 wake_up_process(child); 194 wake_up_process(child);
176 break; 195 break;
@@ -196,6 +215,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
196 ubc_usercnt += 1; 215 ubc_usercnt += 1;
197 child->thread.ubc_pc = pc; 216 child->thread.ubc_pc = pc;
198 217
218 set_tsk_thread_flag(child, TIF_SINGLESTEP);
199 child->exit_code = data; 219 child->exit_code = data;
200 /* give it a chance to run. */ 220 /* give it a chance to run. */
201 wake_up_process(child); 221 wake_up_process(child);
@@ -248,14 +268,15 @@ asmlinkage void do_syscall_trace(void)
248{ 268{
249 struct task_struct *tsk = current; 269 struct task_struct *tsk = current;
250 270
251 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 271 if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
272 !test_thread_flag(TIF_SINGLESTEP))
252 return; 273 return;
253 if (!(tsk->ptrace & PT_PTRACED)) 274 if (!(tsk->ptrace & PT_PTRACED))
254 return; 275 return;
255 /* the 0x80 provides a way for the tracing parent to distinguish 276 /* the 0x80 provides a way for the tracing parent to distinguish
256 between a syscall stop and SIGTRAP delivery */ 277 between a syscall stop and SIGTRAP delivery */
257 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 278 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
258 ? 0x80 : 0)); 279 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
259 280
260 /* 281 /*
261 * this isn't the same as continuing with a signal, but it will do 282 * this isn't the same as continuing with a signal, but it will do
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 32f10a03fbb5..9f39ef1f73da 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -589,6 +589,8 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
589 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 589 if (test_thread_flag(TIF_RESTORE_SIGMASK))
590 clear_thread_flag(TIF_RESTORE_SIGMASK); 590 clear_thread_flag(TIF_RESTORE_SIGMASK);
591 } 591 }
592
593 return;
592 } 594 }
593 595
594 no_signal: 596 no_signal:
@@ -598,7 +600,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
598 if (regs->regs[0] == -ERESTARTNOHAND || 600 if (regs->regs[0] == -ERESTARTNOHAND ||
599 regs->regs[0] == -ERESTARTSYS || 601 regs->regs[0] == -ERESTARTSYS ||
600 regs->regs[0] == -ERESTARTNOINTR) { 602 regs->regs[0] == -ERESTARTNOINTR) {
601 regs->regs[0] = save_r0; 603 regs->regs[0] = save_r0;
602 regs->pc -= 2; 604 regs->pc -= 2;
603 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { 605 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
604 regs->pc -= 2; 606 regs->pc -= 2;
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 75de165867a0..78a6c09875b2 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,6 +3,7 @@
3 * Written by Niibe Yutaka 3 * Written by Niibe Yutaka
4 */ 4 */
5#include <asm/thread_info.h> 5#include <asm/thread_info.h>
6#include <asm/cache.h>
6#include <asm-generic/vmlinux.lds.h> 7#include <asm-generic/vmlinux.lds.h>
7 8
8#ifdef CONFIG_CPU_LITTLE_ENDIAN 9#ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -53,7 +54,7 @@ SECTIONS
53 . = ALIGN(PAGE_SIZE); 54 . = ALIGN(PAGE_SIZE);
54 .data.page_aligned : { *(.data.page_aligned) } 55 .data.page_aligned : { *(.data.page_aligned) }
55 56
56 . = ALIGN(32); 57 . = ALIGN(L1_CACHE_BYTES);
57 __per_cpu_start = .; 58 __per_cpu_start = .;
58 .data.percpu : { *(.data.percpu) } 59 .data.percpu : { *(.data.percpu) }
59 __per_cpu_end = .; 60 __per_cpu_end = .;
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index e0cd4b7f4aeb..981b04089055 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -237,20 +237,10 @@ static inline void flush_cache_4096(unsigned long start,
237/* 237/*
238 * Write back & invalidate the D-cache of the page. 238 * Write back & invalidate the D-cache of the page.
239 * (To avoid "alias" issues) 239 * (To avoid "alias" issues)
240 *
241 * This uses a lazy write-back on UP, which is explicitly
242 * disabled on SMP.
243 */ 240 */
244void flush_dcache_page(struct page *page) 241void flush_dcache_page(struct page *page)
245{ 242{
246#ifndef CONFIG_SMP 243 if (test_bit(PG_mapped, &page->flags)) {
247 struct address_space *mapping = page_mapping(page);
248
249 if (mapping && !mapping_mapped(mapping))
250 set_bit(PG_dcache_dirty, &page->flags);
251 else
252#endif
253 {
254 unsigned long phys = PHYSADDR(page_address(page)); 244 unsigned long phys = PHYSADDR(page_address(page));
255 unsigned long addr = CACHE_OC_ADDRESS_ARRAY; 245 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
256 int i, n; 246 int i, n;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 31f8deb7a158..4896d7376926 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -3,11 +3,11 @@
3 * 3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka 4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2004 Alex Song 5 * Copyright (C) 2004 Alex Song
6 * Copyright (C) 2006 Paul Mundt
7 * 6 *
8 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
10 * for more details. 9 * for more details.
10 *
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mman.h> 13#include <linux/mman.h>
@@ -51,6 +51,7 @@ static inline void cache_wback_all(void)
51 51
52 if ((data & v) == v) 52 if ((data & v) == v)
53 ctrl_outl(data & ~v, addr); 53 ctrl_outl(data & ~v, addr);
54
54 } 55 }
55 56
56 addrstart += current_cpu_data.dcache.way_incr; 57 addrstart += current_cpu_data.dcache.way_incr;
@@ -127,11 +128,7 @@ static void __flush_dcache_page(unsigned long phys)
127 */ 128 */
128void flush_dcache_page(struct page *page) 129void flush_dcache_page(struct page *page)
129{ 130{
130 struct address_space *mapping = page_mapping(page); 131 if (test_bit(PG_mapped, &page->flags))
131
132 if (mapping && !mapping_mapped(mapping))
133 set_bit(PG_dcache_dirty, &page->flags);
134 else
135 __flush_dcache_page(PHYSADDR(page_address(page))); 132 __flush_dcache_page(PHYSADDR(page_address(page)));
136} 133}
137 134
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 969efeceb928..df69da9ca69c 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -23,6 +23,7 @@ extern struct mutex p3map_mutex[];
23 */ 23 */
24void clear_user_page(void *to, unsigned long address, struct page *page) 24void clear_user_page(void *to, unsigned long address, struct page *page)
25{ 25{
26 __set_bit(PG_mapped, &page->flags);
26 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 27 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
27 clear_page(to); 28 clear_page(to);
28 else { 29 else {
@@ -58,6 +59,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
58void copy_user_page(void *to, void *from, unsigned long address, 59void copy_user_page(void *to, void *from, unsigned long address,
59 struct page *page) 60 struct page *page)
60{ 61{
62 __set_bit(PG_mapped, &page->flags);
61 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 63 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
62 copy_page(to, from); 64 copy_page(to, from);
63 else { 65 else {
@@ -82,3 +84,23 @@ void copy_user_page(void *to, void *from, unsigned long address,
82 mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); 84 mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
83 } 85 }
84} 86}
87
88/*
89 * For SH-4, we have our own implementation for ptep_get_and_clear
90 */
91inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
92{
93 pte_t pte = *ptep;
94
95 pte_clear(mm, addr, ptep);
96 if (!pte_not_present(pte)) {
97 unsigned long pfn = pte_pfn(pte);
98 if (pfn_valid(pfn)) {
99 struct page *page = pfn_to_page(pfn);
100 struct address_space *mapping = page_mapping(page);
101 if (!mapping || !mapping_writably_mapped(mapping))
102 __clear_bit(PG_mapped, &page->flags);
103 }
104 }
105 return pte;
106}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index 887ab9d18ccd..a4b015f95a3a 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -7,7 +7,9 @@
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 *
10 */ 11 */
12
11#include <linux/init.h> 13#include <linux/init.h>
12#include <linux/mman.h> 14#include <linux/mman.h>
13#include <linux/mm.h> 15#include <linux/mm.h>
@@ -74,6 +76,7 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
74{ 76{
75 struct page *page = virt_to_page(to); 77 struct page *page = virt_to_page(to);
76 78
79 __set_bit(PG_mapped, &page->flags);
77 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { 80 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
78 clear_page(to); 81 clear_page(to);
79 __flush_wback_region(to, PAGE_SIZE); 82 __flush_wback_region(to, PAGE_SIZE);
@@ -92,11 +95,12 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
92 * @from: P1 address 95 * @from: P1 address
93 * @address: U0 address to be mapped 96 * @address: U0 address to be mapped
94 */ 97 */
95void copy_user_page(void *to, void *from, unsigned long address, 98void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
96 struct page *pg)
97{ 99{
98 struct page *page = virt_to_page(to); 100 struct page *page = virt_to_page(to);
99 101
102
103 __set_bit(PG_mapped, &page->flags);
100 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { 104 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
101 copy_page(to, from); 105 copy_page(to, from);
102 __flush_wback_region(to, PAGE_SIZE); 106 __flush_wback_region(to, PAGE_SIZE);
@@ -108,3 +112,26 @@ void copy_user_page(void *to, void *from, unsigned long address,
108 __flush_wback_region(to, PAGE_SIZE); 112 __flush_wback_region(to, PAGE_SIZE);
109 } 113 }
110} 114}
115
116/*
117 * For SH7705, we have our own implementation for ptep_get_and_clear
118 * Copied from pg-sh4.c
119 */
120inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
121{
122 pte_t pte = *ptep;
123
124 pte_clear(mm, addr, ptep);
125 if (!pte_not_present(pte)) {
126 unsigned long pfn = pte_pfn(pte);
127 if (pfn_valid(pfn)) {
128 struct page *page = pfn_to_page(pfn);
129 struct address_space *mapping = page_mapping(page);
130 if (!mapping || !mapping_writably_mapped(mapping))
131 __clear_bit(PG_mapped, &page->flags);
132 }
133 }
134
135 return pte;
136}
137
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index d2f7b4a2eb05..6f45c1f8a7fe 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -2,17 +2,15 @@
2 * TLB flushing operations for SH with an MMU. 2 * TLB flushing operations for SH with an MMU.
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka 4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 - 2006 Paul Mundt 5 * Copyright (C) 2003 Paul Mundt
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/io.h>
13#include <asm/mmu_context.h> 12#include <asm/mmu_context.h>
14#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
15#include <asm/cacheflush.h>
16 14
17void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 15void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
18{ 16{
@@ -140,54 +138,3 @@ void local_flush_tlb_all(void)
140 ctrl_barrier(); 138 ctrl_barrier();
141 local_irq_restore(flags); 139 local_irq_restore(flags);
142} 140}
143
144void update_mmu_cache(struct vm_area_struct *vma,
145 unsigned long address, pte_t pte)
146{
147 unsigned long flags;
148 unsigned long pteval;
149 unsigned long vpn;
150 struct page *page;
151 unsigned long pfn = pte_pfn(pte);
152 struct address_space *mapping;
153
154 if (!pfn_valid(pfn))
155 return;
156
157 page = pfn_to_page(pfn);
158 mapping = page_mapping(page);
159 if (mapping) {
160 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
161 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
162
163 if (dirty)
164 __flush_wback_region((void *)P1SEGADDR(phys),
165 PAGE_SIZE);
166 }
167
168 local_irq_save(flags);
169
170 /* Set PTEH register */
171 vpn = (address & MMU_VPN_MASK) | get_asid();
172 ctrl_outl(vpn, MMU_PTEH);
173
174 pteval = pte_val(pte);
175
176#ifdef CONFIG_CPU_HAS_PTEA
177 /* Set PTEA register */
178 /* TODO: make this look less hacky */
179 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
180#endif
181
182 /* Set PTEL register */
183 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
184#if defined(CONFIG_SH_WRITETHROUGH) && defined(CONFIG_CPU_SH4)
185 pteval |= _PAGE_WT;
186#endif
187 /* conveniently, we want all the software flags to be 0 anyway */
188 ctrl_outl(pteval, MMU_PTEL);
189
190 /* Load the TLB */
191 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
192 local_irq_restore(flags);
193}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index e5e76eb7ee09..7fbfd5a11ffa 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -8,9 +8,69 @@
8 * 8 *
9 * Released under the terms of the GNU GPL v2.0. 9 * Released under the terms of the GNU GPL v2.0.
10 */ 10 */
11#include <linux/io.h> 11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
12#include <asm/system.h> 24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
13#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37
38 /* Ptrace may call this routine. */
39 if (vma && current->active_mm != vma->vm_mm)
40 return;
41
42#if defined(CONFIG_SH7705_CACHE_32KB)
43 {
44 struct page *page = pte_page(pte);
45 unsigned long pfn = pte_pfn(pte);
46
47 if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
48 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
49
50 __flush_wback_region((void *)P1SEGADDR(phys),
51 PAGE_SIZE);
52 __set_bit(PG_mapped, &page->flags);
53 }
54 }
55#endif
56
57 local_irq_save(flags);
58
59 /* Set PTEH register */
60 vpn = (address & MMU_VPN_MASK) | get_asid();
61 ctrl_outl(vpn, MMU_PTEH);
62
63 pteval = pte_val(pte);
64
65 /* Set PTEL register */
66 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
67 /* conveniently, we want all the software flags to be 0 anyway */
68 ctrl_outl(pteval, MMU_PTEL);
69
70 /* Load the TLB */
71 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
72 local_irq_restore(flags);
73}
14 74
15void local_flush_tlb_one(unsigned long asid, unsigned long page) 75void local_flush_tlb_one(unsigned long asid, unsigned long page)
16{ 76{
@@ -34,3 +94,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
34 for (i = 0; i < ways; i++) 94 for (i = 0; i < ways; i++)
35 ctrl_outl(data, addr + (i << 8)); 95 ctrl_outl(data, addr + (i << 8));
36} 96}
97
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 221e7095473d..f74cf667c8fa 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -8,9 +8,74 @@
8 * 8 *
9 * Released under the terms of the GNU GPL v2.0. 9 * Released under the terms of the GNU GPL v2.0.
10 */ 10 */
11#include <linux/io.h> 11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
12#include <asm/system.h> 24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
13#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37 struct page *page;
38 unsigned long pfn;
39
40 /* Ptrace may call this routine. */
41 if (vma && current->active_mm != vma->vm_mm)
42 return;
43
44 pfn = pte_pfn(pte);
45 if (pfn_valid(pfn)) {
46 page = pfn_to_page(pfn);
47 if (!test_bit(PG_mapped, &page->flags)) {
48 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
49 __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
50 __set_bit(PG_mapped, &page->flags);
51 }
52 }
53
54 local_irq_save(flags);
55
56 /* Set PTEH register */
57 vpn = (address & MMU_VPN_MASK) | get_asid();
58 ctrl_outl(vpn, MMU_PTEH);
59
60 pteval = pte_val(pte);
61
62 /* Set PTEA register */
63 if (cpu_data->flags & CPU_HAS_PTEA)
64 /* TODO: make this look less hacky */
65 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
66
67 /* Set PTEL register */
68 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
69#ifdef CONFIG_SH_WRITETHROUGH
70 pteval |= _PAGE_WT;
71#endif
72 /* conveniently, we want all the software flags to be 0 anyway */
73 ctrl_outl(pteval, MMU_PTEL);
74
75 /* Load the TLB */
76 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
77 local_irq_restore(flags);
78}
14 79
15void local_flush_tlb_one(unsigned long asid, unsigned long page) 80void local_flush_tlb_one(unsigned long asid, unsigned long page)
16{ 81{
@@ -28,3 +93,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
28 ctrl_outl(data, addr); 93 ctrl_outl(data, addr);
29 back_to_P1(); 94 back_to_P1();
30} 95}
96