Submitted By: Jim Gifford (patches at jg555 dot com)
Date: 2006-11-05
Initial Package Version: 2.6.18.2
Origin: Linux-MIPS
Upstream Status: http://www.linux-mips.org/pub/linux/mips/kernel/v2.6/
diff -Naur linux-2.6.18.2/Documentation/mips/time.README linux-mips-2.6.18.2/Documentation/mips/time.README
--- linux-2.6.18.2/Documentation/mips/time.README 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/Documentation/mips/time.README 2006-11-04 14:51:12.000000000 -0800
@@ -63,7 +63,7 @@
a) board_time_init - a function pointer. Invoked at the beginnig of
time_init(). It is optional.
1. (optional) set up RTC routines
- 2. (optional) calibrate and set the mips_counter_frequency
+ 2. (optional) calibrate and set the mips_hpt_frequency
b) plat_timer_setup - a function pointer. Invoked at the end of time_init()
1. (optional) over-ride any decisions made in time_init()
@@ -72,7 +72,7 @@
c) (optional) board-specific RTC routines.
- d) (optional) mips_counter_frequency - It must be definied if the board
+ d) (optional) mips_hpt_frequency - It must be definied if the board
is using CPU counter for timer interrupt or it is using fixed rate
gettimeoffset().
@@ -104,7 +104,7 @@
or use an exnternal timer?
In order to use CPU counter register as the timer interrupt source, you
- must know the counter speed (mips_counter_frequency). It is usually the
+ must know the counter speed (mips_hpt_frequency). It is usually the
same as the CPU speed or an integral divisor of it.
d) decide on whether you want to use high-level or low-level timer
@@ -122,7 +122,7 @@
board_time_init() -
a) (optional) set up RTC routines,
- b) (optional) calibrate and set the mips_counter_frequency
+ b) (optional) calibrate and set the mips_hpt_frequency
(only needed if you intended to use fixed_rate_gettimeoffset
or use cpu counter as timer interrupt source)
diff -Naur linux-2.6.18.2/Makefile linux-mips-2.6.18.2/Makefile
--- linux-2.6.18.2/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -149,10 +149,7 @@
# then ARCH is assigned, getting whatever value it gets normally, and
# SUBARCH is subsequently ignored.
-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
- -e s/arm.*/arm/ -e s/sa110/arm/ \
- -e s/s390x/s390/ -e s/parisc64/parisc/ \
- -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
+SUBARCH := mips
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
diff -Naur linux-2.6.18.2/arch/mips/Kconfig linux-mips-2.6.18.2/arch/mips/Kconfig
--- linux-2.6.18.2/arch/mips/Kconfig 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/Kconfig 2006-11-04 14:51:12.000000000 -0800
@@ -126,7 +126,6 @@
select IRQ_CPU
select IRQ_CPU_RM7K
select IRQ_CPU_RM9K
- select SERIAL_RM9000
select SYS_HAS_CPU_RM9000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
@@ -480,7 +479,6 @@
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
- select ARCH_SPARSEMEM_ENABLE
help
The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer .
@@ -524,8 +522,6 @@
config MACH_VR41XX
bool "NEC VR41XX-based machines"
select SYS_HAS_CPU_VR41XX
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
config PMC_YOSEMITE
bool "PMC-Sierra Yosemite eval board"
@@ -614,6 +610,7 @@
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_NUMA
+ select SYS_SUPPORTS_SMP
help
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
@@ -1200,7 +1197,7 @@
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
- The options selects support for the NEC VR4100 series of processors.
+ The options selects support for the NEC VR41xx series of processors.
Only choose this option if you have one of these processors as a
kernel built with this option will not run on any other type of
processor or vice versa.
@@ -1527,6 +1524,7 @@
select CPU_MIPSR2_SRS
select MIPS_MT
select SMP
+ select SYS_SUPPORTS_SMP
help
This is a kernel model which is known a SMTC or lately has been
marketesed into SMVP.
@@ -1538,6 +1536,7 @@
select CPU_MIPSR2_SRS
select MIPS_MT
select SMP
+ select SYS_SUPPORTS_SMP
help
This is a kernel model which is also known a VSMP or lately
has been marketesed into SMVP.
@@ -1649,9 +1648,7 @@
default y
config IRQ_PER_CPU
- depends on SMP
bool
- default y
#
# - Highmem only makes sense for the 32-bit kernel.
@@ -1691,9 +1688,6 @@
config ARCH_SPARSEMEM_ENABLE
bool
-
-config ARCH_SPARSEMEM_ENABLE
- bool
select SPARSEMEM_STATIC
config NUMA
@@ -1719,6 +1713,7 @@
config SMP
bool "Multi-Processing support"
depends on SYS_SUPPORTS_SMP
+ select IRQ_PER_CPU
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
diff -Naur linux-2.6.18.2/arch/mips/Makefile linux-mips-2.6.18.2/arch/mips/Makefile
--- linux-2.6.18.2/arch/mips/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -63,7 +63,9 @@
ifdef CONFIG_BUILD_ELF64
cflags-y += $(call cc-option,-mno-explicit-relocs)
else
-cflags-y += $(call cc-option,-msym32)
+# -msym32 can not be used for modules since they are loaded into XKSEG
+CFLAGS_MODULE += $(call cc-option,-mno-explicit-relocs)
+CFLAGS_KERNEL += $(call cc-option,-msym32)
endif
endif
@@ -91,8 +93,17 @@
# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
# when fed the toolchain default!
#
-cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB -D__MIPSEB__)
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL -D__MIPSEL__)
+# Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of
+# 2006-10-10 don't properly change the the predefined symbols if -EB / -EL
+# are used, so we kludge that here. A bug has been filed at
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413.
+#
+undef-all += -UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__
+undef-all += -UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__
+predef-be += -DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__
+predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
+cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \
-fno-omit-frame-pointer
@@ -330,6 +341,7 @@
# MIPS SEAD board
#
core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
+cflags-$(CONFIG_MIPS_SEAD) += -Iinclude/asm-mips/mach-mips
load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
#
diff -Naur linux-2.6.18.2/arch/mips/au1000/db1x00/Makefile linux-mips-2.6.18.2/arch/mips/au1000/db1x00/Makefile
--- linux-2.6.18.2/arch/mips/au1000/db1x00/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/au1000/db1x00/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -6,4 +6,3 @@
# Makefile for the Alchemy Semiconductor Db1x00 board.
lib-y := init.o board_setup.o irqmap.o
-obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
diff -Naur linux-2.6.18.2/arch/mips/au1000/db1x00/mirage_ts.c linux-mips-2.6.18.2/arch/mips/au1000/db1x00/mirage_ts.c
--- linux-2.6.18.2/arch/mips/au1000/db1x00/mirage_ts.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/au1000/db1x00/mirage_ts.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,260 +0,0 @@
-/*
- * linux/arch/mips/au1000/db1x00/mirage_ts.c
- *
- * BRIEF MODULE DESCRIPTION
- * Glue between Mirage board-specific touchscreen pieces
- * and generic Wolfson Codec touchscreen support.
- *
- * Based on pb1100_ts.c used in Hydrogen II.
- *
- * Copyright (c) 2003 Embedded Edge, LLC
- * dan@embeddededge.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-/*
- * Imported interface to Wolfson Codec driver.
- */
-extern void *wm97xx_ts_get_handle(int which);
-extern int wm97xx_ts_ready(void* ts_handle);
-extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans);
-extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg);
-extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val);
-extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure);
-extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z);
-
-int wm97xx_comodule_present = 1;
-
-
-#define TS_NAME "mirage_ts"
-
-#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
-#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg)
-
-
-#define PEN_DOWN_IRQ AU1000_GPIO_7
-
-static struct task_struct *ts_task = 0;
-static DECLARE_COMPLETION(ts_complete);
-static DECLARE_WAIT_QUEUE_HEAD(pendown_wait);
-
-#ifdef CONFIG_WM97XX_FIVEWIRETS
-static int release_pressure = 1;
-#else
-static int release_pressure = 50;
-#endif
-
-typedef struct {
- long x;
- long y;
-} DOWN_EVENT;
-
-#define SAMPLE_RATE 50 /* samples per second */
-#define PEN_DEBOUNCE 5 /* samples for settling - fn of SAMPLE_RATE */
-#define PEN_UP_TIMEOUT 10 /* in seconds */
-#define PEN_UP_SETTLE 5 /* samples per second */
-
-static struct {
- int xscale;
- int xtrans;
- int yscale;
- int ytrans;
-} mirage_ts_cal =
-{
-#if 0
- .xscale = 84,
- .xtrans = -157,
- .yscale = 66,
- .ytrans = -150,
-#else
- .xscale = 84,
- .xtrans = -150,
- .yscale = 66,
- .ytrans = -146,
-#endif
-};
-
-
-static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs)
-{
-//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD));
- wake_up(&pendown_wait);
-}
-
-static int ts_thread(void *id)
-{
- static int pen_was_down = 0;
- static DOWN_EVENT pen_xy;
- long x, y, z;
- void *ts; /* handle */
- struct task_struct *tsk = current;
- int timeout = HZ / SAMPLE_RATE;
-
- ts_task = tsk;
-
- daemonize();
- tsk->tty = NULL;
- tsk->policy = SCHED_FIFO;
- tsk->rt_priority = 1;
- strcpy(tsk->comm, "touchscreen");
-
- /* only want to receive SIGKILL */
- spin_lock_irq(&tsk->sigmask_lock);
- siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
- recalc_sigpending(tsk);
- spin_unlock_irq(&tsk->sigmask_lock);
-
- /* get handle for codec */
- ts = wm97xx_ts_get_handle(0);
-
- /* proceed only after everybody is ready */
- wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4);
-
- /* board-specific calibration */
- wm97xx_ts_set_cal(ts,
- mirage_ts_cal.xscale,
- mirage_ts_cal.xtrans,
- mirage_ts_cal.yscale,
- mirage_ts_cal.ytrans);
-
- /* route Wolfson pendown interrupts to our GPIO */
- au_sync();
- wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008);
- au_sync();
- wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008);
- au_sync();
- wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008);
- au_sync();
-
- for (;;) {
- interruptible_sleep_on_timeout(&pendown_wait, timeout);
- disable_irq(PEN_DOWN_IRQ);
- if (signal_pending(tsk)) {
- break;
- }
-
- /* read codec */
- if (!wm97xx_ts_read_data(ts, &x, &y, &z))
- z = 0; /* treat no-data and pen-up the same */
-
- if (signal_pending(tsk)) {
- break;
- }
-
- if (z >= release_pressure) {
- y = ~y; /* top to bottom */
- if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX
- /* bounce ? */
- x = pen_xy.x;
- y = pen_xy.y;
- --pen_was_down;
- } else if (pen_was_down <= 1) {
- pen_xy.x = x;
- pen_xy.y = y;
- if (pen_was_down)
- wm97xx_ts_send_data(ts, x, y, z);
- pen_was_down = PEN_DEBOUNCE;
- }
- //wm97xx_ts_send_data(ts, x, y, z);
- timeout = HZ / SAMPLE_RATE;
- } else {
- if (pen_was_down) {
- if (--pen_was_down)
- z = release_pressure;
- else //THXXX
- wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z);
- }
- /* The pendown signal takes some time to settle after
- * reading the pen pressure so wait a little
- * before enabling the pen.
- */
- if (! pen_was_down) {
-// interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE);
- timeout = HZ * PEN_UP_TIMEOUT;
- }
- }
- enable_irq(PEN_DOWN_IRQ);
- }
- enable_irq(PEN_DOWN_IRQ);
- ts_task = NULL;
- complete(&ts_complete);
- return 0;
-}
-
-static int __init ts_mirage_init(void)
-{
- int ret;
-
- /* pen down signal is connected to GPIO 7 */
-
- ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL);
- if (ret) {
- err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret);
- return ret;
- }
-
- lock_kernel();
- ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES);
- if (ret < 0) {
- unlock_kernel();
- return ret;
- }
- unlock_kernel();
-
- info("Mirage touchscreen IRQ initialized.");
-
- return 0;
-}
-
-static void __exit ts_mirage_exit(void)
-{
- if (ts_task) {
- send_sig(SIGKILL, ts_task, 1);
- wait_for_completion(&ts_complete);
- }
-
- free_irq(PEN_DOWN_IRQ, NULL);
-}
-
-module_init(ts_mirage_init);
-module_exit(ts_mirage_exit);
-
diff -Naur linux-2.6.18.2/arch/mips/cobalt/setup.c linux-mips-2.6.18.2/arch/mips/cobalt/setup.c
--- linux-2.6.18.2/arch/mips/cobalt/setup.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/cobalt/setup.c 2006-11-04 14:51:12.000000000 -0800
@@ -51,8 +51,8 @@
void __init plat_timer_setup(struct irqaction *irq)
{
- /* Load timer value for 1KHz (TCLK is 50MHz) */
- GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
+ /* Load timer value for HZ (TCLK is 50MHz) */
+ GALILEO_OUTL(50*1000*1000 / HZ, GT_TC0_OFS);
/* Enable timer */
GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
diff -Naur linux-2.6.18.2/arch/mips/configs/e55_defconfig linux-mips-2.6.18.2/arch/mips/configs/e55_defconfig
--- linux-2.6.18.2/arch/mips/configs/e55_defconfig 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/configs/e55_defconfig 2006-11-04 14:51:12.000000000 -0800
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul 6 10:04:02 2006
+# Linux kernel version: 2.6.18-rc2
+# Tue Jul 25 23:15:03 2006
#
CONFIG_MIPS=y
@@ -227,7 +227,6 @@
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
@@ -254,7 +253,6 @@
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
# CONFIG_SYS_HYPERVISOR is not set
#
@@ -284,6 +282,7 @@
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -643,6 +642,7 @@
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
@@ -650,7 +650,7 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M"
+CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M"
#
# Security options
diff -Naur linux-2.6.18.2/arch/mips/configs/mpc30x_defconfig linux-mips-2.6.18.2/arch/mips/configs/mpc30x_defconfig
--- linux-2.6.18.2/arch/mips/configs/mpc30x_defconfig 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/configs/mpc30x_defconfig 2006-11-04 14:51:12.000000000 -0800
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul 6 10:04:15 2006
+# Linux kernel version: 2.6.18-rc2
+# Tue Jul 25 23:16:46 2006
#
CONFIG_MIPS=y
@@ -71,7 +71,6 @@
CONFIG_VICTOR_MPC30X=y
# CONFIG_ZAO_CAPCELLA is not set
CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
@@ -168,6 +167,7 @@
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
@@ -841,7 +841,7 @@
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
@@ -982,7 +982,6 @@
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1007,6 +1006,7 @@
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
@@ -1014,7 +1014,7 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="mem=32M console=ttyVR0,19200"
+CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73"
#
# Security options
diff -Naur linux-2.6.18.2/arch/mips/configs/workpad_defconfig linux-mips-2.6.18.2/arch/mips/configs/workpad_defconfig
--- linux-2.6.18.2/arch/mips/configs/workpad_defconfig 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/configs/workpad_defconfig 2006-11-04 14:51:12.000000000 -0800
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul 6 10:04:21 2006
+# Linux kernel version: 2.6.18-rc2
+# Tue Jul 25 23:13:04 2006
#
CONFIG_MIPS=y
@@ -166,6 +166,7 @@
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
@@ -379,6 +380,7 @@
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -855,7 +857,6 @@
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -880,6 +881,7 @@
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
@@ -887,7 +889,7 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M"
+CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
#
# Security options
diff -Naur linux-2.6.18.2/arch/mips/kernel/asm-offsets.c linux-mips-2.6.18.2/arch/mips/kernel/asm-offsets.c
--- linux-2.6.18.2/arch/mips/kernel/asm-offsets.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/asm-offsets.c 2006-11-04 14:51:12.000000000 -0800
@@ -22,7 +22,7 @@
#define offset(string, ptr, member) \
__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
#define constant(string, member) \
- __asm__("\n@@@" string "%x0" : : "ri" (member))
+ __asm__("\n@@@" string "%X0" : : "ri" (member))
#define size(string, size) \
__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
#define linefeed text("")
diff -Naur linux-2.6.18.2/arch/mips/kernel/cpu-probe.c linux-mips-2.6.18.2/arch/mips/kernel/cpu-probe.c
--- linux-2.6.18.2/arch/mips/kernel/cpu-probe.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/cpu-probe.c 2006-11-04 14:51:12.000000000 -0800
@@ -38,15 +38,40 @@
static void r39xx_wait(void)
{
- unsigned long cfg = read_c0_conf();
- write_c0_conf(cfg | TX39_CONF_HALT);
+ local_irq_disable();
+ if (!need_resched())
+ write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
+ local_irq_enable();
}
+/*
+ * There is a race when WAIT instruction executed with interrupt
+ * enabled.
+ * But it is implementation-dependent wheter the pipelie restarts when
+ * a non-enabled interrupt is requested.
+ */
static void r4k_wait(void)
{
- __asm__(".set\tmips3\n\t"
- "wait\n\t"
- ".set\tmips0");
+ __asm__(" .set mips3 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+/*
+ * This variant is preferable as it allows testing need_resched and going to
+ * sleep depending on the outcome atomically. Unfortunately the "It is
+ * implementation-dependent whether the pipeline restarts when a non-enabled
+ * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
+ * using this version a gamble.
+ */
+static void r4k_wait_irqoff(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ __asm__(" .set mips3 \n"
+ " wait \n"
+ " .set mips0 \n");
+ local_irq_enable();
}
/* The Au1xxx wait is available only if using 32khz counter or
@@ -56,17 +81,17 @@
static void au1k_wait(void)
{
/* using the wait instruction makes CP0 counter unusable */
- __asm__(".set mips3\n\t"
- "cache 0x14, 0(%0)\n\t"
- "cache 0x14, 32(%0)\n\t"
- "sync\n\t"
- "nop\n\t"
- "wait\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set mips0\n\t"
+ __asm__(" .set mips3 \n"
+ " cache 0x14, 0(%0) \n"
+ " cache 0x14, 32(%0) \n"
+ " sync \n"
+ " nop \n"
+ " wait \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " .set mips0 \n"
: : "r" (au1k_wait));
}
@@ -110,8 +135,6 @@
case CPU_R5000:
case CPU_NEVADA:
case CPU_RM7000:
- case CPU_RM9000:
- case CPU_TX49XX:
case CPU_4KC:
case CPU_4KEC:
case CPU_4KSC:
@@ -125,6 +148,10 @@
cpu_wait = r4k_wait;
printk(" available.\n");
break;
+ case CPU_TX49XX:
+ cpu_wait = r4k_wait_irqoff;
+ printk(" available.\n");
+ break;
case CPU_AU1000:
case CPU_AU1100:
case CPU_AU1500:
@@ -136,6 +163,14 @@
} else
printk(" unavailable.\n");
break;
+ case CPU_RM9000:
+ if ((c->processor_id & 0x00ff) >= 0x40) {
+ cpu_wait = r4k_wait;
+ printk(" available.\n");
+ } else {
+ printk(" unavailable.\n");
+ }
+ break;
default:
printk(" unavailable.\n");
break;
diff -Naur linux-2.6.18.2/arch/mips/kernel/head.S linux-mips-2.6.18.2/arch/mips/kernel/head.S
--- linux-2.6.18.2/arch/mips/kernel/head.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/head.S 2006-11-04 14:51:12.000000000 -0800
@@ -189,7 +189,8 @@
MTC0 zero, CP0_CONTEXT # clear context register
PTR_LA $28, init_thread_union
- PTR_ADDIU sp, $28, _THREAD_SIZE - 32
+ PTR_LI sp, _THREAD_SIZE - 32
+ PTR_ADDU sp, $28
set_saved_sp sp, t0, t1
PTR_SUBU sp, 4 * SZREG # init stack pointer
diff -Naur linux-2.6.18.2/arch/mips/kernel/irixsig.c linux-mips-2.6.18.2/arch/mips/kernel/irixsig.c
--- linux-2.6.18.2/arch/mips/kernel/irixsig.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/irixsig.c 2006-11-04 14:51:12.000000000 -0800
@@ -17,6 +17,7 @@
#include
#include
+#include
#undef DEBUG_SIG
@@ -172,11 +173,12 @@
return ret;
}
-asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
+void do_irix_signal(struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
+ sigset_t *oldset;
/*
* We want the common case to go fast, which is why we may in certain
@@ -184,19 +186,28 @@
* if so.
*/
if (!user_mode(regs))
- return 1;
+ return;
- if (try_to_freeze())
- goto no_signal;
-
- if (!oldset)
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = ¤t->saved_sigmask;
+ else
oldset = ¤t->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0)
- return handle_signal(signr, &info, &ka, oldset, regs);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+ /* a signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+
+ return;
+ }
-no_signal:
/*
* Who's code doesn't conform to the restartable syscall convention
* dies here!!! The li instruction, a single machine instruction,
@@ -208,8 +219,22 @@
regs->regs[2] == ERESTARTNOINTR) {
regs->cp0_epc -= 8;
}
+ if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
+ regs->regs[2] = __NR_restart_syscall;
+ regs->regs[7] = regs->regs[26];
+ regs->cp0_epc -= 4;
+ }
+ regs->regs[0] = 0; /* Don't deal with this again. */
+ }
+
+ /*
+ * If there's no signal to deliver, we just put the saved sigmask
+ * back
+ */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
}
- return 0;
}
asmlinkage void
@@ -413,7 +438,7 @@
asmlinkage int irix_sigsuspend(struct pt_regs *regs)
{
- sigset_t saveset, newset;
+ sigset_t newset;
sigset_t __user *uset;
uset = (sigset_t __user *) regs->regs[4];
@@ -422,18 +447,15 @@
sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(¤t->sighand->siglock);
- saveset = current->blocked;
+ current->saved_sigmask = current->blocked;
current->blocked = newset;
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- regs->regs[2] = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_irix_signal(&saveset, regs))
- return -EINTR;
- }
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
}
/* hate hate hate... */
diff -Naur linux-2.6.18.2/arch/mips/kernel/linux32.c linux-mips-2.6.18.2/arch/mips/kernel/linux32.c
--- linux-2.6.18.2/arch/mips/kernel/linux32.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/linux32.c 2006-11-04 14:51:12.000000000 -0800
@@ -1053,7 +1053,9 @@
asmlinkage int sys32_personality(unsigned long personality)
{
int ret;
- if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+ personality &= 0xffffffff;
+ if (personality(current->personality) == PER_LINUX32 &&
+ personality == PER_LINUX)
personality = PER_LINUX32;
ret = sys_personality(personality);
if (ret == PER_LINUX32)
@@ -1296,9 +1298,3 @@
return do_fork(clone_flags, newsp, ®s, 0,
parent_tidptr, child_tidptr);
}
-
-extern asmlinkage void sys_set_thread_area(u32 addr);
-asmlinkage void sys32_set_thread_area(u32 addr)
-{
- sys_set_thread_area(AA(addr));
-}
diff -Naur linux-2.6.18.2/arch/mips/kernel/mips-mt.c linux-mips-2.6.18.2/arch/mips/kernel/mips-mt.c
--- linux-2.6.18.2/arch/mips/kernel/mips-mt.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/mips-mt.c 2006-11-04 14:51:12.000000000 -0800
@@ -96,6 +96,10 @@
goto out_unlock;
}
+ retval = security_task_setscheduler(p, 0, NULL);
+ if (retval)
+ goto out_unlock;
+
/* Record new user-specified CPU set for future reference */
p->thread.user_cpus_allowed = new_mask;
@@ -141,8 +145,9 @@
p = find_process_by_pid(pid);
if (!p)
goto out_unlock;
-
- retval = 0;
+ retval = security_task_getscheduler(p);
+ if (retval)
+ goto out_unlock;
cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
diff -Naur linux-2.6.18.2/arch/mips/kernel/proc.c linux-mips-2.6.18.2/arch/mips/kernel/proc.c
--- linux-2.6.18.2/arch/mips/kernel/proc.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/proc.c 2006-11-04 14:51:12.000000000 -0800
@@ -89,9 +89,9 @@
static int show_cpuinfo(struct seq_file *m, void *v)
{
- unsigned int version = current_cpu_data.processor_id;
- unsigned int fp_vers = current_cpu_data.fpu_id;
unsigned long n = (unsigned long) v - 1;
+ unsigned int version = cpu_data[n].processor_id;
+ unsigned int fp_vers = cpu_data[n].fpu_id;
char fmt [64];
#ifdef CONFIG_SMP
@@ -107,9 +107,9 @@
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
- cpu_has_fpu ? " FPU V%d.%d" : "");
- seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ?
- current_cpu_data.cputype : CPU_UNKNOWN],
+ cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
+ seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ?
+ cpu_data[n].cputype : CPU_UNKNOWN],
(version >> 4) & 0x0f, version & 0x0f,
(fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
@@ -118,7 +118,7 @@
seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
seq_printf(m, "microsecond timers\t: %s\n",
cpu_has_counter ? "yes" : "no");
- seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize);
+ seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
seq_printf(m, "extra interrupt vector\t: %s\n",
cpu_has_divec ? "yes" : "no");
seq_printf(m, "hardware watchpoint\t: %s\n",
diff -Naur linux-2.6.18.2/arch/mips/kernel/process.c linux-mips-2.6.18.2/arch/mips/kernel/process.c
--- linux-2.6.18.2/arch/mips/kernel/process.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/process.c 2006-11-04 14:51:12.000000000 -0800
@@ -114,7 +114,7 @@
status |= KU_USER;
regs->cp0_status = status;
clear_used_math();
- lose_fpu();
+ clear_fpu_owner();
if (cpu_has_dsp)
__init_dsp();
regs->cp0_epc = pc;
@@ -281,62 +281,63 @@
} *schedule_frame, mfinfo[64];
static int mfinfo_num;
-static int __init get_frame_info(struct mips_frame_info *info)
+static inline int is_ra_save_ins(union mips_instruction *ip)
{
- int i;
- void *func = info->func;
- union mips_instruction *ip = (union mips_instruction *)func;
+ /* sw / sd $ra, offset($sp) */
+ return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+ ip->i_format.rs == 29 &&
+ ip->i_format.rt == 31;
+}
+
+static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
+{
+ if (ip->j_format.opcode == jal_op)
+ return 1;
+ if (ip->r_format.opcode != spec_op)
+ return 0;
+ return ip->r_format.func == jalr_op || ip->r_format.func == jr_op;
+}
+
+static inline int is_sp_move_ins(union mips_instruction *ip)
+{
+ /* addiu/daddiu sp,sp,-imm */
+ if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
+ return 0;
+ if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
+ return 1;
+ return 0;
+}
+
+static int get_frame_info(struct mips_frame_info *info)
+{
+ union mips_instruction *ip = info->func;
+ int i, max_insns =
+ min(128UL, info->func_size / sizeof(union mips_instruction));
+
info->pc_offset = -1;
info->frame_size = 0;
- for (i = 0; i < 128; i++, ip++) {
- /* if jal, jalr, jr, stop. */
- if (ip->j_format.opcode == jal_op ||
- (ip->r_format.opcode == spec_op &&
- (ip->r_format.func == jalr_op ||
- ip->r_format.func == jr_op)))
- break;
- if (info->func_size && i >= info->func_size / 4)
+ for (i = 0; i < max_insns; i++, ip++) {
+
+ if (is_jal_jalr_jr_ins(ip))
break;
- if (
-#ifdef CONFIG_32BIT
- ip->i_format.opcode == addiu_op &&
-#endif
-#ifdef CONFIG_64BIT
- ip->i_format.opcode == daddiu_op &&
-#endif
- ip->i_format.rs == 29 &&
- ip->i_format.rt == 29) {
- /* addiu/daddiu sp,sp,-imm */
- if (info->frame_size)
- continue;
- info->frame_size = - ip->i_format.simmediate;
+ if (!info->frame_size) {
+ if (is_sp_move_ins(ip))
+ info->frame_size = - ip->i_format.simmediate;
+ continue;
}
-
- if (
-#ifdef CONFIG_32BIT
- ip->i_format.opcode == sw_op &&
-#endif
-#ifdef CONFIG_64BIT
- ip->i_format.opcode == sd_op &&
-#endif
- ip->i_format.rs == 29 &&
- ip->i_format.rt == 31) {
- /* sw / sd $ra, offset($sp) */
- if (info->pc_offset != -1)
- continue;
+ if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
info->pc_offset =
ip->i_format.simmediate / sizeof(long);
+ break;
}
}
- if (info->pc_offset == -1 || info->frame_size == 0) {
- if (func == schedule)
- printk("Can't analyze prologue code at %p\n", func);
- info->pc_offset = -1;
- info->frame_size = 0;
- }
-
- return 0;
+ if (info->frame_size && info->pc_offset >= 0) /* nested */
+ return 0;
+ if (info->pc_offset < 0) /* leaf */
+ return 1;
+ /* prologue seems boggus... */
+ return -1;
}
static int __init frame_info_init(void)
@@ -368,7 +369,14 @@
schedule_frame = &mfinfo[0];
#endif
for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++)
- get_frame_info(&mfinfo[i]);
+ get_frame_info(mfinfo + i);
+
+ /*
+ * Without schedule() frame info, result given by
+ * thread_saved_pc() and get_wchan() are not reliable.
+ */
+ if (schedule_frame->pc_offset < 0)
+ printk("Can't analyze schedule() prologue at %p\n", schedule);
mfinfo_num = i;
return 0;
@@ -427,6 +435,8 @@
if (i < 0)
break;
+ if (mfinfo[i].pc_offset < 0)
+ break;
pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
if (!mfinfo[i].frame_size)
break;
@@ -437,3 +447,49 @@
return pc;
}
+#ifdef CONFIG_KALLSYMS
+/* used by show_backtrace() */
+unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long ra)
+{
+ unsigned long stack_page;
+ struct mips_frame_info info;
+ char *modname;
+ char namebuf[KSYM_NAME_LEN + 1];
+ unsigned long size, ofs;
+ int leaf;
+
+ stack_page = (unsigned long)task_stack_page(task);
+ if (!stack_page)
+ return 0;
+
+ if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
+ return 0;
+ if (ofs == 0)
+ return 0;
+
+ info.func = (void *)(pc - ofs);
+ info.func_size = ofs; /* analyze from start to ofs */
+ leaf = get_frame_info(&info);
+ if (leaf < 0)
+ return 0;
+
+ if (*sp < stack_page ||
+ *sp + info.frame_size > stack_page + THREAD_SIZE - 32)
+ return 0;
+
+ if (leaf)
+ /*
+ * For some extreme cases, get_frame_info() can
+ * consider wrongly a nested function as a leaf
+ * one. In that cases avoid to return always the
+ * same value.
+ */
+ pc = pc != ra ? ra : 0;
+ else
+ pc = ((unsigned long *)(*sp))[info.pc_offset];
+
+ *sp += info.frame_size;
+ return __kernel_text_address(pc) ? pc : 0;
+}
+#endif
diff -Naur linux-2.6.18.2/arch/mips/kernel/ptrace.c linux-mips-2.6.18.2/arch/mips/kernel/ptrace.c
--- linux-2.6.18.2/arch/mips/kernel/ptrace.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/ptrace.c 2006-11-04 14:51:12.000000000 -0800
@@ -20,12 +20,12 @@
#include
#include
#include
-#include
#include
#include
#include
#include
-#include
+#include
+#include
#include
#include
@@ -106,6 +106,7 @@
int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
{
int i;
+ unsigned int tmp;
if (!access_ok(VERIFY_WRITE, data, 33 * 8))
return -EIO;
@@ -121,10 +122,10 @@
__put_user (child->thread.fpu.fcr31, data + 64);
+ preempt_disable();
if (cpu_has_fpu) {
- unsigned int flags, tmp;
+ unsigned int flags;
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
@@ -138,11 +139,11 @@
__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
write_c0_status(flags);
}
- preempt_enable();
- __put_user (tmp, data + 65);
} else {
- __put_user ((__u32) 0, data + 65);
+ tmp = 0;
}
+ preempt_enable();
+ __put_user (tmp, data + 65);
return 0;
}
@@ -245,16 +246,17 @@
unsigned int mtflags;
#endif /* CONFIG_MIPS_MT_SMTC */
- if (!cpu_has_fpu)
+ preempt_disable();
+ if (!cpu_has_fpu) {
+ preempt_enable();
break;
+ }
#ifdef CONFIG_MIPS_MT_SMTC
/* Read-modify-write of Status must be atomic */
local_irq_save(irqflags);
mtflags = dmt();
#endif /* CONFIG_MIPS_MT_SMTC */
-
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
@@ -471,12 +473,16 @@
*/
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{
+ /* do the secure computing check first */
+ secure_computing(regs->orig_eax);
+
if (unlikely(current->audit_context) && entryexit)
audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
regs->regs[2]);
if (!(current->ptrace & PT_PTRACED))
goto out;
+
if (!test_thread_flag(TIF_SYSCALL_TRACE))
goto out;
@@ -494,9 +500,14 @@
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
- out:
+
+out:
+ /* There is no ->orig_eax and that's quite intensional for now making
+ this work will require some work in various other place before it's
+ more than a placebo. */
+
if (unlikely(current->audit_context) && !entryexit)
- audit_syscall_entry(audit_arch(), regs->regs[2],
- regs->regs[4], regs->regs[5],
- regs->regs[6], regs->regs[7]);
+ audit_syscall_entry(audit_arch(), regs->orig_eax,
+ regs->regs[4], regs->regs[5],
+ regs->regs[6], regs->regs[7]);
}
diff -Naur linux-2.6.18.2/arch/mips/kernel/ptrace32.c linux-mips-2.6.18.2/arch/mips/kernel/ptrace32.c
--- linux-2.6.18.2/arch/mips/kernel/ptrace32.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/ptrace32.c 2006-11-04 14:51:12.000000000 -0800
@@ -175,7 +175,9 @@
unsigned int mtflags;
#endif /* CONFIG_MIPS_MT_SMTC */
+ preempt_disable();
if (!cpu_has_fpu) {
+ preempt_enable();
tmp = 0;
break;
}
@@ -186,7 +188,6 @@
mtflags = dmt();
#endif /* CONFIG_MIPS_MT_SMTC */
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
diff -Naur linux-2.6.18.2/arch/mips/kernel/r4k_switch.S linux-mips-2.6.18.2/arch/mips/kernel/r4k_switch.S
--- linux-2.6.18.2/arch/mips/kernel/r4k_switch.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/r4k_switch.S 2006-11-04 14:51:12.000000000 -0800
@@ -85,7 +85,12 @@
move $28, a2
cpu_restore_nonscratch a1
+#if (_THREAD_SIZE - 32) < 0x10000
PTR_ADDIU t0, $28, _THREAD_SIZE - 32
+#else
+ PTR_LI t0, _THREAD_SIZE - 32
+ PTR_ADDU t0, $28
+#endif
set_saved_sp t0, t1, t2
#ifdef CONFIG_MIPS_MT_SMTC
/* Read-modify-writes of Status must be atomic on a VPE */
diff -Naur linux-2.6.18.2/arch/mips/kernel/scall32-o32.S linux-mips-2.6.18.2/arch/mips/kernel/scall32-o32.S
--- linux-2.6.18.2/arch/mips/kernel/scall32-o32.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/scall32-o32.S 2006-11-04 14:51:12.000000000 -0800
@@ -662,6 +662,8 @@
sys sys_tee 4
sys sys_vmsplice 4
sys sys_move_pages 6
+ sys sys_set_robust_list 2
+ sys sys_get_robust_list 3
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff -Naur linux-2.6.18.2/arch/mips/kernel/scall64-64.S linux-mips-2.6.18.2/arch/mips/kernel/scall64-64.S
--- linux-2.6.18.2/arch/mips/kernel/scall64-64.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/scall64-64.S 2006-11-04 14:51:12.000000000 -0800
@@ -466,3 +466,5 @@
PTR sys_tee /* 5265 */
PTR sys_vmsplice
PTR sys_move_pages
+ PTR sys_set_robust_list
+ PTR sys_get_robust_list
diff -Naur linux-2.6.18.2/arch/mips/kernel/scall64-n32.S linux-mips-2.6.18.2/arch/mips/kernel/scall64-n32.S
--- linux-2.6.18.2/arch/mips/kernel/scall64-n32.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/scall64-n32.S 2006-11-04 14:51:12.000000000 -0800
@@ -247,7 +247,7 @@
PTR sys_capset
PTR sys32_rt_sigpending /* 6125 */
PTR compat_sys_rt_sigtimedwait
- PTR sys_rt_sigqueueinfo
+ PTR sys32_rt_sigqueueinfo
PTR sysn32_rt_sigsuspend
PTR sys32_sigaltstack
PTR compat_sys_utime /* 6130 */
@@ -280,7 +280,7 @@
PTR sys_sync
PTR sys_acct
PTR sys32_settimeofday
- PTR sys_mount /* 6160 */
+ PTR compat_sys_mount /* 6160 */
PTR sys_umount
PTR sys_swapon
PTR sys_swapoff
@@ -390,5 +390,7 @@
PTR sys_splice
PTR sys_sync_file_range
PTR sys_tee
- PTR sys_vmsplice /* 6271 */
+ PTR sys_vmsplice /* 6270 */
PTR sys_move_pages
+ PTR compat_sys_set_robust_list
+ PTR compat_sys_get_robust_list
diff -Naur linux-2.6.18.2/arch/mips/kernel/scall64-o32.S linux-mips-2.6.18.2/arch/mips/kernel/scall64-o32.S
--- linux-2.6.18.2/arch/mips/kernel/scall64-o32.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/scall64-o32.S 2006-11-04 14:51:12.000000000 -0800
@@ -226,7 +226,7 @@
PTR sys_ni_syscall /* was sys_stat */
PTR sys_lseek
PTR sys_getpid /* 4020 */
- PTR sys_mount
+ PTR compat_sys_mount
PTR sys_oldumount
PTR sys_setuid
PTR sys_getuid
@@ -498,7 +498,7 @@
PTR sys_mknodat /* 4290 */
PTR sys_fchownat
PTR compat_sys_futimesat
- PTR compat_sys_newfstatat
+ PTR sys_newfstatat
PTR sys_unlinkat
PTR sys_renameat /* 4295 */
PTR sys_linkat
@@ -514,4 +514,6 @@
PTR sys_tee
PTR sys_vmsplice
PTR compat_sys_move_pages
+ PTR compat_sys_set_robust_list
+ PTR compat_sys_get_robust_list /* 4310 */
.size sys_call_table,.-sys_call_table
diff -Naur linux-2.6.18.2/arch/mips/kernel/signal.c linux-mips-2.6.18.2/arch/mips/kernel/signal.c
--- linux-2.6.18.2/arch/mips/kernel/signal.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/signal.c 2006-11-04 14:51:12.000000000 -0800
@@ -424,15 +424,11 @@
if (!user_mode(regs))
return;
- if (try_to_freeze())
- goto no_signal;
-
if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = ¤t->saved_sigmask;
else
oldset = ¤t->blocked;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
@@ -446,9 +442,10 @@
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
+
+ return;
}
-no_signal:
/*
* Who's code doesn't conform to the restartable syscall convention
* dies here!!! The li instruction, a single machine instruction,
@@ -466,6 +463,7 @@
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
/*
diff -Naur linux-2.6.18.2/arch/mips/kernel/signal32.c linux-mips-2.6.18.2/arch/mips/kernel/signal32.c
--- linux-2.6.18.2/arch/mips/kernel/signal32.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/signal32.c 2006-11-04 14:51:12.000000000 -0800
@@ -815,9 +815,6 @@
if (!user_mode(regs))
return;
- if (try_to_freeze())
- goto no_signal;
-
if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = ¤t->saved_sigmask;
else
@@ -836,9 +833,10 @@
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
+
+ return;
}
-no_signal:
/*
* Who's code doesn't conform to the restartable syscall convention
* dies here!!! The li instruction, a single machine instruction,
@@ -856,6 +854,7 @@
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
/*
diff -Naur linux-2.6.18.2/arch/mips/kernel/smp-mt.c linux-mips-2.6.18.2/arch/mips/kernel/smp-mt.c
--- linux-2.6.18.2/arch/mips/kernel/smp-mt.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/smp-mt.c 2006-11-04 14:51:12.000000000 -0800
@@ -203,7 +203,7 @@
write_vpe_c0_config( read_c0_config());
/* make sure there are no software interrupts pending */
- write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0));
+ write_vpe_c0_cause(0);
/* Propagate Config7 */
write_vpe_c0_config7(read_c0_config7());
diff -Naur linux-2.6.18.2/arch/mips/kernel/smp.c linux-mips-2.6.18.2/arch/mips/kernel/smp.c
--- linux-2.6.18.2/arch/mips/kernel/smp.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/smp.c 2006-11-04 14:51:12.000000000 -0800
@@ -467,14 +467,18 @@
static int __init topology_init(void)
{
- int cpu;
- int ret;
+ int i, ret;
- for_each_present_cpu(cpu) {
- ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
+#ifdef CONFIG_NUMA
+ for_each_online_node(i)
+ register_one_node(i);
+#endif /* CONFIG_NUMA */
+
+ for_each_present_cpu(i) {
+ ret = register_cpu(&per_cpu(cpu_devices, i), i);
if (ret)
printk(KERN_WARNING "topology_init: register_cpu %d "
- "failed (%d)\n", cpu, ret);
+ "failed (%d)\n", i, ret);
}
return 0;
diff -Naur linux-2.6.18.2/arch/mips/kernel/smtc-asm.S linux-mips-2.6.18.2/arch/mips/kernel/smtc-asm.S
--- linux-2.6.18.2/arch/mips/kernel/smtc-asm.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/smtc-asm.S 2006-11-04 14:51:12.000000000 -0800
@@ -8,7 +8,7 @@
#include
#include
#include
-#include
+#include
/*
* "Software Interrupt" linkage.
diff -Naur linux-2.6.18.2/arch/mips/kernel/syscall.c linux-mips-2.6.18.2/arch/mips/kernel/syscall.c
--- linux-2.6.18.2/arch/mips/kernel/syscall.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/syscall.c 2006-11-04 14:51:12.000000000 -0800
@@ -263,7 +263,7 @@
return error;
}
-void sys_set_thread_area(unsigned long addr)
+asmlinkage int sys_set_thread_area(unsigned long addr)
{
struct thread_info *ti = task_thread_info(current);
@@ -271,6 +271,8 @@
/* If some future MIPS implementation has this register in hardware,
* we will need to update it here (and in context switches). */
+
+ return 0;
}
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
diff -Naur linux-2.6.18.2/arch/mips/kernel/traps.c linux-mips-2.6.18.2/arch/mips/kernel/traps.c
--- linux-2.6.18.2/arch/mips/kernel/traps.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/traps.c 2006-11-04 14:51:12.000000000 -0800
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
@@ -64,7 +65,7 @@
extern asmlinkage void handle_reserved(void);
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
- struct mips_fpu_struct *ctx);
+ struct mips_fpu_struct *ctx, int has_fpu);
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -72,28 +73,68 @@
void (*board_ejtag_handler_setup)(void);
void (*board_bind_eic_interrupt)(int irq, int regset);
-/*
- * These constant is for searching for possible module text segments.
- * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
- */
-#define MODULE_RANGE (8*1024*1024)
+
+static void show_raw_backtrace(unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)reg29;
+ unsigned long addr;
+
+ printk("Call Trace:");
+#ifdef CONFIG_KALLSYMS
+ printk("\n");
+#endif
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+ printk("\n");
+}
+
+#ifdef CONFIG_KALLSYMS
+static int raw_show_trace;
+static int __init set_raw_show_trace(char *str)
+{
+ raw_show_trace = 1;
+ return 1;
+}
+__setup("raw_show_trace", set_raw_show_trace);
+
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long ra);
+
+static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
+{
+ unsigned long sp = regs->regs[29];
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ show_raw_backtrace(sp);
+ return;
+ }
+ printk("Call Trace:\n");
+ do {
+ print_ip_sym(pc);
+ pc = unwind_stack(task, &sp, pc, ra);
+ ra = 0;
+ } while (pc);
+ printk("\n");
+}
+#else
+#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
+#endif
/*
* This routine abuses get_user()/put_user() to reference pointers
* with at least a bit of error checking ...
*/
-void show_stack(struct task_struct *task, unsigned long *sp)
+static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
long stackdata;
int i;
-
- if (!sp) {
- if (task && task != current)
- sp = (unsigned long *) task->thread.reg29;
- else
- sp = (unsigned long *) &sp;
- }
+ unsigned long *sp = (unsigned long *)regs->regs[29];
printk("Stack :");
i = 0;
@@ -114,32 +155,48 @@
i++;
}
printk("\n");
+ show_backtrace(task, regs);
}
-void show_trace(struct task_struct *task, unsigned long *stack)
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
{
- const int field = 2 * sizeof(unsigned long);
- unsigned long addr;
-
- if (!stack) {
- if (task && task != current)
- stack = (unsigned long *) task->thread.reg29;
- else
- stack = (unsigned long *) &stack;
- }
-
- printk("Call Trace:");
-#ifdef CONFIG_KALLSYMS
- printk("\n");
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set noat\n\t"
+#ifdef CONFIG_64BIT
+ "1: dla $1, 1b\n\t"
+ "sd $1, %0\n\t"
+ "sd $29, %1\n\t"
+ "sd $31, %2\n\t"
+#else
+ "1: la $1, 1b\n\t"
+ "sw $1, %0\n\t"
+ "sw $29, %1\n\t"
+ "sw $31, %2\n\t"
#endif
- while (!kstack_end(stack)) {
- addr = *stack++;
- if (__kernel_text_address(addr)) {
- printk(" [<%0*lx>] ", field, addr);
- print_symbol("%s\n", addr);
+ ".set pop\n\t"
+ : "=m" (regs->cp0_epc),
+ "=m" (regs->regs[29]), "=m" (regs->regs[31])
+ : : "memory");
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+ struct pt_regs regs;
+ if (sp) {
+ regs.regs[29] = (unsigned long)sp;
+ regs.regs[31] = 0;
+ regs.cp0_epc = 0;
+ } else {
+ if (task && task != current) {
+ regs.regs[29] = task->thread.reg29;
+ regs.regs[31] = 0;
+ regs.cp0_epc = task->thread.reg31;
+ } else {
+ prepare_frametrace(®s);
}
}
- printk("\n");
+ show_stacktrace(task, ®s);
}
/*
@@ -147,9 +204,15 @@
*/
void dump_stack(void)
{
- unsigned long stack;
+ struct pt_regs regs;
- show_trace(current, &stack);
+ /*
+ * Remove any garbage that may be in regs (specially func
+ * addresses) to avoid show_raw_backtrace() to report them
+ */
+ memset(®s, 0, sizeof(regs));
+ prepare_frametrace(®s);
+ show_backtrace(current, ®s);
}
EXPORT_SYMBOL(dump_stack);
@@ -268,8 +331,7 @@
print_modules();
printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
current->comm, current->pid, current_thread_info(), current);
- show_stack(current, (long *) regs->regs[29]);
- show_trace(current, (long *) regs->regs[29]);
+ show_stacktrace(current, regs);
show_code((unsigned int *) regs->cp0_epc);
printk("\n");
}
@@ -292,6 +354,16 @@
printk("%s[#%d]:\n", str, ++die_counter);
show_registers(regs);
spin_unlock_irq(&die_lock);
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops) {
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+ panic("Fatal exception");
+ }
+
do_exit(SIGSEGV);
}
@@ -601,7 +673,7 @@
preempt_enable();
/* Run the emulator */
- sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu);
+ sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu, 1);
preempt_disable();
@@ -751,11 +823,13 @@
set_used_math();
}
- preempt_enable();
-
- if (!cpu_has_fpu) {
- int sig = fpu_emulator_cop1Handler(regs,
- ¤t->thread.fpu);
+ if (cpu_has_fpu) {
+ preempt_enable();
+ } else {
+ int sig;
+ preempt_enable();
+ sig = fpu_emulator_cop1Handler(regs,
+ ¤t->thread.fpu, 0);
if (sig)
force_sig(sig, current);
#ifdef CONFIG_MIPS_MT_FPAFF
diff -Naur linux-2.6.18.2/arch/mips/kernel/vmlinux.lds.S linux-mips-2.6.18.2/arch/mips/kernel/vmlinux.lds.S
--- linux-2.6.18.2/arch/mips/kernel/vmlinux.lds.S 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/vmlinux.lds.S 2006-11-04 14:51:12.000000000 -0800
@@ -50,6 +50,16 @@
/* writeable */
.data : { /* Data */
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
+ /*
+ * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
+ * limits the maximum alignment to at most 32kB and results in the following
+ * warning:
+ *
+ * CC arch/mips/kernel/init_task.o
+ * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’
+ * is greater than maximum object file alignment. Using 32768
+ */
+ . = ALIGN(_PAGE_SIZE);
*(.data.init_task)
*(.data)
diff -Naur linux-2.6.18.2/arch/mips/kernel/vpe.c linux-mips-2.6.18.2/arch/mips/kernel/vpe.c
--- linux-2.6.18.2/arch/mips/kernel/vpe.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/kernel/vpe.c 2006-11-04 14:51:12.000000000 -0800
@@ -768,10 +768,16 @@
*/
write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));
+
+ back_to_back_c0_hazard();
+
/* Set up the XTC bit in vpeconf0 to point at our tc */
write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
| (t->index << VPECONF0_XTC_SHIFT));
+ back_to_back_c0_hazard();
+
/* enable this VPE */
write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
diff -Naur linux-2.6.18.2/arch/mips/lib/Makefile linux-mips-2.6.18.2/arch/mips/lib/Makefile
--- linux-2.6.18.2/arch/mips/lib/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/lib/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -5,8 +5,6 @@
lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
strnlen_user.o uncached.o
-obj-y += iomap.o
-
# libgcc-style stuff needed in the kernel
lib-y += ashldi3.o ashrdi3.o lshrdi3.o
diff -Naur linux-2.6.18.2/arch/mips/lib/iomap.c linux-mips-2.6.18.2/arch/mips/lib/iomap.c
--- linux-2.6.18.2/arch/mips/lib/iomap.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/lib/iomap.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * iomap.c, Memory Mapped I/O routines for MIPS architecture.
- *
- * This code is based on lib/iomap.c, by Linus Torvalds.
- *
- * Copyright (C) 2004-2005 Yoichi Yuasa
- *
- * This program is free software; you can redistribute it and/or modify
- * it 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include
-#include
-#include
-
-#include
-
-void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
- unsigned long end;
-
- end = port + nr - 1UL;
- if (ioport_resource.start > port ||
- ioport_resource.end < end || port > end)
- return NULL;
-
- return (void __iomem *)(mips_io_port_base + port);
-}
-
-void ioport_unmap(void __iomem *addr)
-{
-}
-EXPORT_SYMBOL(ioport_map);
-EXPORT_SYMBOL(ioport_unmap);
-
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
-{
- unsigned long start, len, flags;
-
- if (dev == NULL)
- return NULL;
-
- start = pci_resource_start(dev, bar);
- len = pci_resource_len(dev, bar);
- if (!start || !len)
- return NULL;
-
- if (maxlen != 0 && len > maxlen)
- len = maxlen;
-
- flags = pci_resource_flags(dev, bar);
- if (flags & IORESOURCE_IO)
- return ioport_map(start, len);
- if (flags & IORESOURCE_MEM) {
- if (flags & IORESOURCE_CACHEABLE)
- return ioremap_cachable(start, len);
- return ioremap_nocache(start, len);
- }
-
- return NULL;
-}
-
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
-{
- iounmap(addr);
-}
-EXPORT_SYMBOL(pci_iomap);
-EXPORT_SYMBOL(pci_iounmap);
diff -Naur linux-2.6.18.2/arch/mips/lib-32/dump_tlb.c linux-mips-2.6.18.2/arch/mips/lib-32/dump_tlb.c
--- linux-2.6.18.2/arch/mips/lib-32/dump_tlb.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/lib-32/dump_tlb.c 2006-11-04 14:51:12.000000000 -0800
@@ -40,8 +40,6 @@
return "256Mb";
#endif
}
-
- return "unknown";
}
#define BARRIER() \
diff -Naur linux-2.6.18.2/arch/mips/lib-64/dump_tlb.c linux-mips-2.6.18.2/arch/mips/lib-64/dump_tlb.c
--- linux-2.6.18.2/arch/mips/lib-64/dump_tlb.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/lib-64/dump_tlb.c 2006-11-04 14:51:12.000000000 -0800
@@ -31,8 +31,6 @@
case PM_256M: return "256Mb";
#endif
}
-
- return "unknown";
}
#define BARRIER() \
@@ -149,7 +147,7 @@
printk("Addr == %08lx\n", addr);
printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd);
- page_dir = pgd_offset(t->mm, 0);
+ page_dir = pgd_offset(t->mm, 0UL);
printk("page_dir == %016lx\n", (unsigned long) page_dir);
pgd = pgd_offset(t->mm, addr);
@@ -184,13 +182,13 @@
dump_list_process(current, address);
}
-unsigned int vtop(void *address)
+unsigned long vtop(void *address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- unsigned int addr, paddr;
+ unsigned long addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
diff -Naur linux-2.6.18.2/arch/mips/math-emu/cp1emu.c linux-mips-2.6.18.2/arch/mips/math-emu/cp1emu.c
--- linux-2.6.18.2/arch/mips/math-emu/cp1emu.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/math-emu/cp1emu.c 2006-11-04 14:51:12.000000000 -0800
@@ -38,8 +38,6 @@
#include
#include
-#include
-#include
#include
#include
#include
@@ -1233,7 +1231,8 @@
return 0;
}
-int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu)
{
unsigned long oldepc, prevepc;
mips_instruction insn;
@@ -1263,7 +1262,7 @@
ieee754_csr.rm = mips_rm[ieee754_csr.rm];
}
- if (cpu_has_fpu)
+ if (has_fpu)
break;
if (sig)
break;
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/atlas/atlas_int.c linux-mips-2.6.18.2/arch/mips/mips-boards/atlas/atlas_int.c
--- linux-2.6.18.2/arch/mips/mips-boards/atlas/atlas_int.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/atlas/atlas_int.c 2006-11-04 14:51:12.000000000 -0800
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard
+ * Maciej W. Rozycki
*
* ########################################################################
*
@@ -25,17 +27,20 @@
*/
#include
#include
+#include
#include
#include
#include
#include
-#include
+#include
#include
+#include
+#include
+
#include
#include
-#include
-
+#include
static struct atlas_ictrl_regs *atlas_hw0_icregs;
@@ -47,13 +52,13 @@
void disable_atlas_irq(unsigned int irq_nr)
{
- atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE));
+ atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE);
iob();
}
void enable_atlas_irq(unsigned int irq_nr)
{
- atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE));
+ atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE);
iob();
}
@@ -107,7 +112,7 @@
if (unlikely(int_status == 0))
return;
- irq = ATLASINT_BASE + ls1bit32(int_status);
+ irq = ATLAS_INT_BASE + ls1bit32(int_status);
DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
@@ -161,15 +166,14 @@
}
/*
- * IRQs on the Atlas board look basically (barring software IRQs which we
- * don't use at all and all external interrupt sources are combined together
- * on hardware interrupt 0 (MIPS IRQ 2)) like:
+ * IRQs on the Atlas board look basically like (all external interrupt
+ * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)):
*
- * MIPS IRQ Source
+ * MIPS IRQ Source
* -------- ------
- * 0 Software (ignored)
- * 1 Software (ignored)
- * 2 Combined hardware interrupt (hw0)
+ * 0 Software 0 (reschedule IPI on MT)
+ * 1 Software 1 (remote call IPI on MT)
+ * 2 Combined Atlas hardware interrupt (hw0)
* 3 Hardware (ignored)
* 4 Hardware (ignored)
* 5 Hardware (ignored)
@@ -179,7 +183,7 @@
* We handle the IRQ according to _our_ priority which is:
*
* Highest ---- R4k Timer
- * Lowest ---- Combined hardware interrupt
+ * Lowest ---- Software 0
*
* then we just return, if multiple IRQs are pending then we will just take
* another exception, big deal.
@@ -193,17 +197,19 @@
if (irq == MIPSCPU_INT_ATLAS)
atlas_hw0_irqdispatch(regs);
- else if (irq > 0)
+ else if (irq >= 0)
do_IRQ(MIPSCPU_INT_BASE + irq, regs);
else
spurious_interrupt(regs);
}
-void __init arch_init_irq(void)
+static inline void init_atlas_irqs (int base)
{
int i;
- atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *));
+ atlas_hw0_icregs = (struct atlas_ictrl_regs *)
+ ioremap(ATLAS_ICTRL_REGS_BASE,
+ sizeof(struct atlas_ictrl_regs *));
/*
* Mask out all interrupt by writing "1" to all bit position in
@@ -211,7 +217,7 @@
*/
atlas_hw0_icregs->intrsten = 0xffffffff;
- for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
+ for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
irq_desc[i].depth = 1;
@@ -219,3 +225,62 @@
spin_lock_init(&irq_desc[i].lock);
}
}
+
+static struct irqaction atlasirq = {
+ .handler = no_action,
+ .name = "Atlas cascade"
+};
+
+msc_irqmap_t __initdata msc_irqmap[] = {
+ {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
+};
+int __initdata msc_nr_irqs = sizeof(msc_irqmap) / sizeof(*msc_irqmap);
+
+msc_irqmap_t __initdata msc_eicirqmap[] = {
+ {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
+};
+int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap) / sizeof(*msc_eicirqmap);
+
+void __init arch_init_irq(void)
+{
+ init_atlas_irqs(ATLAS_INT_BASE);
+
+ if (!cpu_has_veic)
+ mips_cpu_irq_init(MIPSCPU_INT_BASE);
+
+ switch(mips_revision_corid) {
+ case MIPS_REVISION_CORID_CORE_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_24K:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ if (cpu_has_veic)
+ init_msc_irqs (MSC01E_INT_BASE,
+ msc_eicirqmap, msc_nr_eicirqs);
+ else
+ init_msc_irqs (MSC01C_INT_BASE,
+ msc_irqmap, msc_nr_irqs);
+ }
+
+
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
+ setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq);
+ } else if (cpu_has_vint) {
+ set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch);
+#ifdef CONFIG_MIPS_MT_SMTC
+ setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS,
+ &atlasirq, (0x100 << MIPSCPU_INT_ATLAS));
+#else /* Not SMTC */
+ setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ } else
+ setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
+}
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/atlas/atlas_setup.c linux-mips-2.6.18.2/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-2.6.18.2/arch/mips/mips-boards/atlas/atlas_setup.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/atlas/atlas_setup.c 2006-11-04 14:51:12.000000000 -0800
@@ -77,7 +77,7 @@
#else
s.iobase = ATLAS_UART_REGS_BASE+3;
#endif
- s.irq = ATLASINT_UART;
+ s.irq = ATLAS_INT_UART;
s.uartclk = ATLAS_BASE_BAUD * 16;
s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
s.iotype = UPIO_PORT;
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/generic/memory.c linux-mips-2.6.18.2/arch/mips/mips-boards/generic/memory.c
--- linux-2.6.18.2/arch/mips/mips-boards/generic/memory.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/generic/memory.c 2006-11-04 14:51:12.000000000 -0800
@@ -176,7 +176,7 @@
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
continue;
- addr = boot_mem_map.map[i].addr;
+ addr = PAGE_ALIGN(boot_mem_map.map[i].addr);
while (addr < boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size) {
ClearPageReserved(virt_to_page(__va(addr)));
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/generic/time.c linux-mips-2.6.18.2/arch/mips/mips-boards/generic/time.c
--- linux-2.6.18.2/arch/mips/mips-boards/generic/time.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/generic/time.c 2006-11-04 14:51:12.000000000 -0800
@@ -41,8 +41,13 @@
#include
#include
+
+#ifdef CONFIG_MIPS_ATLAS
+#include
+#endif
+#ifdef CONFIG_MIPS_MALTA
#include
-#include
+#endif
unsigned long cpu_khz;
@@ -92,10 +97,9 @@
irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int r2 = cpu_has_mips_r2;
#ifdef CONFIG_MIPS_MT_SMTC
- /*
+ /*
* In an SMTC system, one Count/Compare set exists per VPE.
* Which TC within a VPE gets the interrupt is essentially
* random - we only know that it shouldn't be one with
@@ -108,29 +112,46 @@
* the general MIPS timer_interrupt routine.
*/
+ int vpflags;
+
/*
- * DVPE is necessary so long as cross-VPE interrupts
- * are done via read-modify-write of Cause register.
+ * We could be here due to timer interrupt,
+ * perf counter overflow, or both.
*/
- int vpflags = dvpe();
- write_c0_compare (read_c0_count() - 1);
- clear_c0_cause(CPUCTR_IMASKBIT);
- evpe(vpflags);
-
- if (cpu_data[cpu].vpe_id == 0) {
- timer_interrupt(irq, dev_id, regs);
- scroll_display_message();
- } else
- write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
- smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+ if (read_c0_cause() & (1 << 26))
+ perf_irq(regs);
- if (cpu != 0)
+ if (read_c0_cause() & (1 << 30)) {
+ /* If timer interrupt, make it de-assert */
+ write_c0_compare (read_c0_count() - 1);
/*
- * Other CPUs should do profiling and process accounting
+ * DVPE is necessary so long as cross-VPE interrupts
+ * are done via read-modify-write of Cause register.
*/
- local_timer_interrupt(irq, dev_id, regs);
-
+ vpflags = dvpe();
+ clear_c0_cause(CPUCTR_IMASKBIT);
+ evpe(vpflags);
+ /*
+ * There are things we only want to do once per tick
+ * in an "MP" system. One TC of each VPE will take
+ * the actual timer interrupt. The others will get
+ * timer broadcast IPIs. We use whoever it is that takes
+ * the tick on VPE 0 to run the full timer_interrupt().
+ */
+ if (cpu_data[cpu].vpe_id == 0) {
+ timer_interrupt(irq, NULL, regs);
+ smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+ scroll_display_message();
+ } else {
+ write_c0_compare(read_c0_count() +
+ (mips_hpt_frequency/HZ));
+ local_timer_interrupt(irq, dev_id, regs);
+ smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+ }
+ }
#else /* CONFIG_MIPS_MT_SMTC */
+ int r2 = cpu_has_mips_r2;
+
if (cpu == 0) {
/*
* CPU 0 handles the global timer interrupt job and process
@@ -161,14 +182,13 @@
*/
local_timer_interrupt(irq, dev_id, regs);
}
-#endif /* CONFIG_MIPS_MT_SMTC */
-
out:
+#endif /* CONFIG_MIPS_MT_SMTC */
return IRQ_HANDLED;
}
/*
- * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/malta/malta_int.c linux-mips-2.6.18.2/arch/mips/mips-boards/malta/malta_int.c
--- linux-2.6.18.2/arch/mips/mips-boards/malta/malta_int.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/malta/malta_int.c 2006-11-04 14:51:12.000000000 -0800
@@ -208,23 +208,23 @@
unsigned int a0 = 7;
unsigned int t0;
- t0 = s0 & 0xf000;
+ t0 = pending & 0xf000;
t0 = t0 < 1;
t0 = t0 << 2;
a0 = a0 - t0;
- s0 = s0 << t0;
+ pending = pending << t0;
- t0 = s0 & 0xc000;
+ t0 = pending & 0xc000;
t0 = t0 < 1;
t0 = t0 << 1;
a0 = a0 - t0;
- s0 = s0 << t0;
+ pending = pending << t0;
- t0 = s0 & 0x8000;
+ t0 = pending & 0x8000;
t0 = t0 < 1;
//t0 = t0 << 2;
a0 = a0 - t0;
- //s0 = s0 << t0;
+ //pending = pending << t0;
return a0;
#endif
diff -Naur linux-2.6.18.2/arch/mips/mips-boards/sim/sim_time.c linux-mips-2.6.18.2/arch/mips/mips-boards/sim/sim_time.c
--- linux-2.6.18.2/arch/mips/mips-boards/sim/sim_time.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mips-boards/sim/sim_time.c 2006-11-04 14:51:12.000000000 -0800
@@ -103,7 +103,7 @@
/*
- * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
diff -Naur linux-2.6.18.2/arch/mips/mm/c-r3k.c linux-mips-2.6.18.2/arch/mips/mm/c-r3k.c
--- linux-2.6.18.2/arch/mips/mm/c-r3k.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/c-r3k.c 2006-11-04 14:51:12.000000000 -0800
@@ -335,7 +335,7 @@
flush_cache_mm = r3k_flush_cache_mm;
flush_cache_range = r3k_flush_cache_range;
flush_cache_page = r3k_flush_cache_page;
- flush_icache_page = r3k_flush_icache_page;
+ __flush_icache_page = r3k_flush_icache_page;
flush_icache_range = r3k_flush_icache_range;
flush_cache_sigtramp = r3k_flush_cache_sigtramp;
diff -Naur linux-2.6.18.2/arch/mips/mm/c-r4k.c linux-mips-2.6.18.2/arch/mips/mm/c-r4k.c
--- linux-2.6.18.2/arch/mips/mm/c-r4k.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/c-r4k.c 2006-11-04 14:51:12.000000000 -0800
@@ -475,7 +475,7 @@
}
}
if (exec) {
- if (cpu_has_vtag_icache) {
+ if (cpu_has_vtag_icache && mm == current->active_mm) {
int cpu = smp_processor_id();
if (cpu_context(cpu, mm) != 0)
@@ -599,7 +599,7 @@
* We're not sure of the virtual address(es) involved here, so
* we have to flush the entire I-cache.
*/
- if (cpu_has_vtag_icache) {
+ if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
int cpu = smp_processor_id();
if (cpu_context(cpu, vma->vm_mm) != 0)
@@ -1242,7 +1242,7 @@
clear_c0_config(CONF_CU);
break;
/*
- * We need to catch the ealry Alchemy SOCs with
+ * We need to catch the early Alchemy SOCs with
* the write-only co_config.od bit and set it back to one...
*/
case CPU_AU1000: /* rev. DA, HA, HB */
@@ -1291,7 +1291,7 @@
__flush_cache_all = r4k___flush_cache_all;
flush_cache_mm = r4k_flush_cache_mm;
flush_cache_page = r4k_flush_cache_page;
- flush_icache_page = r4k_flush_icache_page;
+ __flush_icache_page = r4k_flush_icache_page;
flush_cache_range = r4k_flush_cache_range;
flush_cache_sigtramp = r4k_flush_cache_sigtramp;
diff -Naur linux-2.6.18.2/arch/mips/mm/c-sb1.c linux-mips-2.6.18.2/arch/mips/mm/c-sb1.c
--- linux-2.6.18.2/arch/mips/mm/c-sb1.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/c-sb1.c 2006-11-04 14:51:12.000000000 -0800
@@ -155,6 +155,26 @@
}
/*
+ * Invalidate a range of the icache. The addresses are virtual, and
+ * the cache is virtually indexed and tagged. However, we don't
+ * necessarily have the right ASID context, so use index ops instead
+ * of hit ops.
+ */
+static inline void __sb1_flush_icache_range(unsigned long start,
+ unsigned long end)
+{
+ start &= ~(icache_line_size - 1);
+ end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
+
+ while (start != end) {
+ cache_set_op(Index_Invalidate_I, start & icache_index_mask);
+ start += icache_line_size;
+ }
+ mispredict();
+ sync();
+}
+
+/*
* Flush the icache for a given physical page. Need to writeback the
* dcache first, then invalidate the icache. If the page isn't
* executable, nothing is required.
@@ -173,8 +193,11 @@
/*
* Bumping the ASID is probably cheaper than the flush ...
*/
- if (cpu_context(cpu, vma->vm_mm) != 0)
- drop_mmu_context(vma->vm_mm, cpu);
+ if (vma->vm_mm == current->active_mm) {
+ if (cpu_context(cpu, vma->vm_mm) != 0)
+ drop_mmu_context(vma->vm_mm, cpu);
+ } else
+ __sb1_flush_icache_range(addr, addr + PAGE_SIZE);
}
#ifdef CONFIG_SMP
@@ -210,26 +233,6 @@
__attribute__((alias("local_sb1_flush_cache_page")));
#endif
-/*
- * Invalidate a range of the icache. The addresses are virtual, and
- * the cache is virtually indexed and tagged. However, we don't
- * necessarily have the right ASID context, so use index ops instead
- * of hit ops.
- */
-static inline void __sb1_flush_icache_range(unsigned long start,
- unsigned long end)
-{
- start &= ~(icache_line_size - 1);
- end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
-
- while (start != end) {
- cache_set_op(Index_Invalidate_I, start & icache_index_mask);
- start += icache_line_size;
- }
- mispredict();
- sync();
-}
-
/*
* Invalidate all caches on this CPU
@@ -326,9 +329,12 @@
* If there's a context, bump the ASID (cheaper than a flush,
* since we don't know VAs!)
*/
- if (cpu_context(cpu, vma->vm_mm) != 0) {
- drop_mmu_context(vma->vm_mm, cpu);
- }
+ if (vma->vm_mm == current->active_mm) {
+ if (cpu_context(cpu, vma->vm_mm) != 0)
+ drop_mmu_context(vma->vm_mm, cpu);
+ } else
+ __sb1_flush_icache_range(start, start + PAGE_SIZE);
+
}
#ifdef CONFIG_SMP
@@ -520,7 +526,7 @@
/* These routines are for Icache coherence with the Dcache */
flush_icache_range = sb1_flush_icache_range;
- flush_icache_page = sb1_flush_icache_page;
+ __flush_icache_page = sb1_flush_icache_page;
flush_icache_all = __sb1_flush_icache_all; /* local only */
/* This implies an Icache flush too, so can't be nop'ed */
diff -Naur linux-2.6.18.2/arch/mips/mm/c-tx39.c linux-mips-2.6.18.2/arch/mips/mm/c-tx39.c
--- linux-2.6.18.2/arch/mips/mm/c-tx39.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/c-tx39.c 2006-11-04 14:51:12.000000000 -0800
@@ -382,7 +382,7 @@
flush_cache_mm = (void *) tx39h_flush_icache_all;
flush_cache_range = (void *) tx39h_flush_icache_all;
flush_cache_page = (void *) tx39h_flush_icache_all;
- flush_icache_page = (void *) tx39h_flush_icache_all;
+ __flush_icache_page = (void *) tx39h_flush_icache_all;
flush_icache_range = (void *) tx39h_flush_icache_all;
flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
@@ -408,7 +408,7 @@
flush_cache_mm = tx39_flush_cache_mm;
flush_cache_range = tx39_flush_cache_range;
flush_cache_page = tx39_flush_cache_page;
- flush_icache_page = tx39_flush_icache_page;
+ __flush_icache_page = tx39_flush_icache_page;
flush_icache_range = tx39_flush_icache_range;
flush_cache_sigtramp = tx39_flush_cache_sigtramp;
diff -Naur linux-2.6.18.2/arch/mips/mm/cache.c linux-mips-2.6.18.2/arch/mips/mm/cache.c
--- linux-2.6.18.2/arch/mips/mm/cache.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/cache.c 2006-11-04 14:51:12.000000000 -0800
@@ -25,7 +25,7 @@
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
unsigned long pfn);
void (*flush_icache_range)(unsigned long start, unsigned long end);
-void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
+void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
/* MIPS specific cache operations */
void (*flush_cache_sigtramp)(unsigned long addr);
@@ -70,6 +70,8 @@
struct address_space *mapping = page_mapping(page);
unsigned long addr;
+ if (PageHighMem(page))
+ return;
if (mapping && !mapping_mapped(mapping)) {
SetPageDcacheDirty(page);
return;
@@ -91,16 +93,16 @@
{
struct page *page;
unsigned long pfn, addr;
+ int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
pfn = pte_pfn(pte);
- if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) &&
- Page_dcache_dirty(page)) {
- if (pages_do_alias((unsigned long)page_address(page),
- address & PAGE_MASK)) {
- addr = (unsigned long) page_address(page);
+ if (unlikely(!pfn_valid(pfn)))
+ return;
+ page = pfn_to_page(pfn);
+ if (page_mapping(page) && Page_dcache_dirty(page)) {
+ addr = (unsigned long) page_address(page);
+ if (exec || pages_do_alias(addr, address & PAGE_MASK))
flush_data_cache_page(addr);
- }
-
ClearPageDcacheDirty(page);
}
}
diff -Naur linux-2.6.18.2/arch/mips/mm/fault.c linux-mips-2.6.18.2/arch/mips/mm/fault.c
--- linux-2.6.18.2/arch/mips/mm/fault.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/fault.c 2006-11-04 14:51:12.000000000 -0800
@@ -89,7 +89,7 @@
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
goto bad_area;
}
diff -Naur linux-2.6.18.2/arch/mips/mm/init.c linux-mips-2.6.18.2/arch/mips/mm/init.c
--- linux-2.6.18.2/arch/mips/mm/init.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/init.c 2006-11-04 14:51:12.000000000 -0800
@@ -30,11 +30,39 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
+#include
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include
+
+#define ENTER_CRITICAL(flags) \
+ { \
+ unsigned int mvpflags; \
+ local_irq_save(flags);\
+ mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+ evpe(mvpflags); \
+ local_irq_restore(flags); \
+ }
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -80,13 +108,184 @@
return 1UL << order;
}
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
+/*
+ * These are almost like kmap_atomic / kunmap_atmic except they take an
+ * additional address argument as the hint.
+ */
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+#ifdef CONFIG_MIPS_MT_SMTC
+static pte_t *kmap_coherent_pte;
+static void __init kmap_coherent_init(void)
+{
+ unsigned long vaddr;
+
+ /* cache the first coherent kmap pte */
+ vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+ kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+#else
+static inline void kmap_coherent_init(void) {}
+#endif
+
+static inline void *kmap_coherent(struct page *page, unsigned long addr)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr, flags, entrylo;
+ unsigned long old_ctx;
+ pte_t pte;
+ int tlbidx;
+
+ inc_preempt_count();
+ idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
+#ifdef CONFIG_MIPS_MT_SMTC
+ idx += FIX_N_COLOURS * smp_processor_id();
+#endif
+ vaddr = __fix_to_virt(FIX_CMAP_END - idx);
+ pte = mk_pte(page, PAGE_KERNEL);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ entrylo = pte.pte_high;
+#else
+ entrylo = pte_val(pte) >> 6;
+#endif
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ write_c0_entryhi(vaddr & (PAGE_MASK << 1));
+ write_c0_entrylo0(entrylo);
+ write_c0_entrylo1(entrylo);
+#ifdef CONFIG_MIPS_MT_SMTC
+ set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+ /* preload TLB instead of local_flush_tlb_one() */
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ BARRIER;
+ tlbidx = read_c0_index();
+ mtc0_tlbw_hazard();
+ if (tlbidx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+#else
+ tlbidx = read_c0_wired();
+ write_c0_wired(tlbidx + 1);
+ write_c0_index(tlbidx);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+#endif
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+
+ return (void*) vaddr;
+}
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+static inline void kunmap_coherent(struct page *page)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+ unsigned int wired;
+ unsigned long flags, old_ctx;
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ wired = read_c0_wired() - 1;
+ write_c0_wired(wired);
+ write_c0_index(wired);
+ write_c0_entryhi(UNIQUE_ENTRYHI(wired));
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+#endif
+ dec_preempt_count();
+ preempt_check_resched();
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *vfrom, *vto;
+
+ vto = kmap_atomic(to, KM_USER1);
+ if (cpu_has_dc_aliases) {
+ vfrom = kmap_coherent(from, vaddr);
+ copy_page(vto, vfrom);
+ kunmap_coherent(from);
+ } else {
+ vfrom = kmap_atomic(from, KM_USER0);
+ copy_page(vto, vfrom);
+ kunmap_atomic(vfrom, KM_USER0);
+ }
+ if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) ||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)vto);
+ kunmap_atomic(vto, KM_USER1);
+ /* Make sure this page is cleared on other CPU's too before using it */
+ smp_wmb();
+}
+
+EXPORT_SYMBOL(copy_user_highpage);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *to)
+{
+ if (cpu_has_dc_aliases) {
+ struct page *from = virt_to_page(vfrom);
+ vfrom = kmap_coherent(from, vaddr);
+ copy_page(vto, vfrom);
+ kunmap_coherent(from);
+ } else
+ copy_page(vto, vfrom);
+ if (!cpu_has_ic_fills_f_dc ||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)vto);
+}
+
+EXPORT_SYMBOL(copy_user_page);
+
+void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases) {
+ void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(vto, src, len);
+ kunmap_coherent(page);
+ } else
+ memcpy(dst, src, len);
+ if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+EXPORT_SYMBOL(copy_to_user_page);
+
+void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases) {
+ void *vfrom =
+ kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(dst, vfrom, len);
+ kunmap_coherent(page);
+ } else
+ memcpy(dst, src, len);
+}
+
+EXPORT_SYMBOL(copy_from_user_page);
+
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
static void __init kmap_init(void)
{
unsigned long kmap_vstart;
@@ -97,11 +296,12 @@
kmap_prot = PAGE_KERNEL;
}
+#endif /* CONFIG_HIGHMEM */
-#ifdef CONFIG_32BIT
void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
@@ -122,7 +322,7 @@
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd(pte));
+ set_pmd(pmd, __pmd((unsigned long)pte));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
@@ -132,9 +332,8 @@
}
j = 0;
}
+#endif
}
-#endif /* CONFIG_32BIT */
-#endif /* CONFIG_HIGHMEM */
#ifndef CONFIG_NEED_MULTIPLE_NODES
extern void pagetable_init(void);
@@ -175,6 +374,7 @@
#ifdef CONFIG_HIGHMEM
kmap_init();
#endif
+ kmap_coherent_init();
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
diff -Naur linux-2.6.18.2/arch/mips/mm/ioremap.c linux-mips-2.6.18.2/arch/mips/mm/ioremap.c
--- linux-2.6.18.2/arch/mips/mm/ioremap.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/ioremap.c 2006-11-04 14:51:12.000000000 -0800
@@ -176,7 +176,7 @@
#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
-void __iounmap(volatile void __iomem *addr)
+void __iounmap(const volatile void __iomem *addr)
{
struct vm_struct *p;
diff -Naur linux-2.6.18.2/arch/mips/mm/pg-r4k.c linux-mips-2.6.18.2/arch/mips/mm/pg-r4k.c
--- linux-2.6.18.2/arch/mips/mm/pg-r4k.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/pg-r4k.c 2006-11-04 14:51:12.000000000 -0800
@@ -270,6 +270,20 @@
emit_instruction(mi);
}
+static inline void build_addiu_a2(unsigned long offset)
+{
+ union mips_instruction mi;
+
+ BUG_ON(offset > 0x7fff);
+
+ mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+ mi.i_format.rs = 6; /* $a2 */
+ mi.i_format.rt = 6; /* $a2 */
+ mi.i_format.simmediate = offset;
+
+ emit_instruction(mi);
+}
+
static inline void build_addiu_a1(unsigned long offset)
{
union mips_instruction mi;
@@ -333,6 +347,7 @@
void __init build_clear_page(void)
{
unsigned int loop_start;
+ unsigned long off;
epc = (unsigned int *) &clear_page_array;
instruction_pending = 0;
@@ -369,7 +384,12 @@
}
}
- build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+ off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
+ if (off > 0x7fff) {
+ build_addiu_a2_a0(off >> 1);
+ build_addiu_a2(off >> 1);
+ } else
+ build_addiu_a2_a0(off);
if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
@@ -420,12 +440,18 @@
void __init build_copy_page(void)
{
unsigned int loop_start;
+ unsigned long off;
epc = (unsigned int *) ©_page_array;
store_offset = load_offset = 0;
instruction_pending = 0;
- build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+ off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
+ if (off > 0x7fff) {
+ build_addiu_a2_a0(off >> 1);
+ build_addiu_a2(off >> 1);
+ } else
+ build_addiu_a2_a0(off);
if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
diff -Naur linux-2.6.18.2/arch/mips/mm/pgtable-32.c linux-mips-2.6.18.2/arch/mips/mm/pgtable-32.c
--- linux-2.6.18.2/arch/mips/mm/pgtable-32.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/pgtable-32.c 2006-11-04 14:51:12.000000000 -0800
@@ -31,9 +31,10 @@
void __init pagetable_init(void)
{
-#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
- pgd_t *pgd, *pgd_base;
+ pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+ pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
@@ -44,7 +45,6 @@
pgd_init((unsigned long)swapper_pg_dir
+ sizeof(pgd_t) * USER_PTRS_PER_PGD);
-#ifdef CONFIG_HIGHMEM
pgd_base = swapper_pg_dir;
/*
@@ -53,6 +53,7 @@
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, 0, pgd_base);
+#ifdef CONFIG_HIGHMEM
/*
* Permanent kmaps:
*/
diff -Naur linux-2.6.18.2/arch/mips/mm/pgtable-64.c linux-mips-2.6.18.2/arch/mips/mm/pgtable-64.c
--- linux-2.6.18.2/arch/mips/mm/pgtable-64.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/pgtable-64.c 2006-11-04 14:51:12.000000000 -0800
@@ -8,6 +8,7 @@
*/
#include
#include
+#include
#include
void pgd_init(unsigned long page)
@@ -52,7 +53,17 @@
void __init pagetable_init(void)
{
+ unsigned long vaddr;
+ pgd_t *pgd_base;
+
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+
+ pgd_base = swapper_pg_dir;
+ /*
+ * Fixed mappings:
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ fixrange_init(vaddr, 0, pgd_base);
}
diff -Naur linux-2.6.18.2/arch/mips/mm/tlbex.c linux-mips-2.6.18.2/arch/mips/mm/tlbex.c
--- linux-2.6.18.2/arch/mips/mm/tlbex.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/mm/tlbex.c 2006-11-04 14:51:12.000000000 -0800
@@ -102,7 +102,7 @@
insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
- insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+ insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -145,6 +145,7 @@
{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
+ { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
{ insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -385,6 +386,7 @@
I_u2u1u3(_dsll32);
I_u2u1u3(_dsra);
I_u2u1u3(_dsrl);
+I_u2u1u3(_dsrl32);
I_u3u1u2(_dsubu);
I_0(_eret);
I_u1(_j);
@@ -996,7 +998,12 @@
#endif
l_vmalloc_done(l, *p);
- i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
+
+ if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */
+ i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+ else
+ i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+
i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
@@ -1073,7 +1080,7 @@
static __init void build_adjust_context(u32 **p, unsigned int ctx)
{
- unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+ unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
switch (current_cpu_data.cputype) {
diff -Naur linux-2.6.18.2/arch/mips/oprofile/op_model_mipsxx.c linux-mips-2.6.18.2/arch/mips/oprofile/op_model_mipsxx.c
--- linux-2.6.18.2/arch/mips/oprofile/op_model_mipsxx.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/oprofile/op_model_mipsxx.c 2006-11-04 14:51:12.000000000 -0800
@@ -30,16 +30,18 @@
#define M_COUNTER_OVERFLOW (1UL << 31)
#ifdef CONFIG_MIPS_MT_SMP
-#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define vpe_id() smp_processor_id()
#else
-#define WHAT 0
+#define WHAT 0
+#define vpe_id() smp_processor_id()
#endif
#define __define_perf_accessors(r, n, np) \
\
static inline unsigned int r_c0_ ## r ## n(void) \
{ \
- unsigned int cpu = smp_processor_id(); \
+ unsigned int cpu = vpe_id(); \
\
switch (cpu) { \
case 0: \
@@ -54,7 +56,7 @@
\
static inline void w_c0_ ## r ## n(unsigned int value) \
{ \
- unsigned int cpu = smp_processor_id(); \
+ unsigned int cpu = vpe_id(); \
\
switch (cpu) { \
case 0: \
@@ -217,7 +219,7 @@
{
int counters = __n_counters();
-#ifndef CONFIG_SMP
+#ifdef CONFIG_MIPS_MT_SMP
if (current_cpu_data.cputype == CPU_34K)
return counters >> 1;
#endif
diff -Naur linux-2.6.18.2/arch/mips/pci/Makefile linux-mips-2.6.18.2/arch/mips/pci/Makefile
--- linux-2.6.18.2/arch/mips/pci/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/pci/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -28,7 +28,7 @@
obj-$(CONFIG_LASAT) += pci-lasat.o
obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o
obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
-obj-$(CONFIG_MIPS_EV96100) += fixup-ev64120.o
+obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o
obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o
obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o
diff -Naur linux-2.6.18.2/arch/mips/pci/fixup-atlas.c linux-mips-2.6.18.2/arch/mips/pci/fixup-atlas.c
--- linux-2.6.18.2/arch/mips/pci/fixup-atlas.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/pci/fixup-atlas.c 2006-11-04 14:51:12.000000000 -0800
@@ -21,16 +21,16 @@
#include
-#define PCIA ATLASINT_PCIA
-#define PCIB ATLASINT_PCIB
-#define PCIC ATLASINT_PCIC
-#define PCID ATLASINT_PCID
-#define INTA ATLASINT_INTA
-#define INTB ATLASINT_INTB
-#define ETH ATLASINT_ETH
-#define INTC ATLASINT_INTC
-#define SCSI ATLASINT_SCSI
-#define INTD ATLASINT_INTD
+#define PCIA ATLAS_INT_PCIA
+#define PCIB ATLAS_INT_PCIB
+#define PCIC ATLAS_INT_PCIC
+#define PCID ATLAS_INT_PCID
+#define INTA ATLAS_INT_INTA
+#define INTB ATLAS_INT_INTB
+#define ETH ATLAS_INT_ETH
+#define INTC ATLAS_INT_INTC
+#define SCSI ATLAS_INT_SCSI
+#define INTD ATLAS_INT_INTD
static char irq_tab[][5] __initdata = {
/* INTA INTB INTC INTD */
diff -Naur linux-2.6.18.2/arch/mips/pci/fixup-tb0219.c linux-mips-2.6.18.2/arch/mips/pci/fixup-tb0219.c
--- linux-2.6.18.2/arch/mips/pci/fixup-tb0219.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/pci/fixup-tb0219.c 2006-11-04 14:51:12.000000000 -0800
@@ -2,7 +2,7 @@
* fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
*
* Copyright (C) 2003 Megasolution Inc.
- * Copyright (C) 2004 Yoichi Yuasa
+ * Copyright (C) 2004-2005 Yoichi Yuasa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff -Naur linux-2.6.18.2/arch/mips/pci/ops-au1000.c linux-mips-2.6.18.2/arch/mips/pci/ops-au1000.c
--- linux-2.6.18.2/arch/mips/pci/ops-au1000.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/pci/ops-au1000.c 2006-11-04 14:51:12.000000000 -0800
@@ -110,7 +110,7 @@
if (first_cfg) {
/* reserve a wired entry for pci config accesses */
first_cfg = 0;
- pci_cfg_vm = get_vm_area(0x2000, 0);
+ pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
if (!pci_cfg_vm)
panic (KERN_ERR "PCI unable to get vm area\n");
pci_cfg_wired_entry = read_c0_wired();
diff -Naur linux-2.6.18.2/arch/mips/qemu/Makefile linux-mips-2.6.18.2/arch/mips/qemu/Makefile
--- linux-2.6.18.2/arch/mips/qemu/Makefile 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/qemu/Makefile 2006-11-04 14:51:12.000000000 -0800
@@ -4,4 +4,5 @@
obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
+obj-$(CONFIG_VT) += q-vga.o
obj-$(CONFIG_SMP) += q-smp.o
diff -Naur linux-2.6.18.2/arch/mips/qemu/q-setup.c linux-mips-2.6.18.2/arch/mips/qemu/q-setup.c
--- linux-2.6.18.2/arch/mips/qemu/q-setup.c 2006-11-03 17:33:58.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/qemu/q-setup.c 2006-11-04 14:51:12.000000000 -0800
@@ -2,6 +2,7 @@
#include
#include
+extern void qvga_init(void);
extern void qemu_reboot_setup(void);
#define QEMU_PORT_BASE 0xb4000000
@@ -23,5 +24,9 @@
void __init plat_mem_setup(void)
{
set_io_port_base(QEMU_PORT_BASE);
+#ifdef CONFIG_VT
+ qvga_init();
+#endif
+
qemu_reboot_setup();
}
diff -Naur linux-2.6.18.2/arch/mips/qemu/q-vga.c linux-mips-2.6.18.2/arch/mips/qemu/q-vga.c
--- linux-2.6.18.2/arch/mips/qemu/q-vga.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-mips-2.6.18.2/arch/mips/qemu/q-vga.c 2006-11-04 14:51:12.000000000 -0800
@@ -0,0 +1,189 @@
+/*
+ * 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
+ * for more details.
+ *
+ * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This will eventually go into the qemu firmware.
+ */
+#include
+#include
+#include
+#include
+#include