summaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-23 14:05:01 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-23 14:05:01 +0000
commitf3627cbe9236a062012c836f3b6ee311b43f63f2 (patch)
treeae854838b9a73b35bd0f3b8f42e5fb7f9cb1d5a9 /arch/sh
parentfea12a7b3f20bc135ab533491411e9ff753c01c8 (diff)
Merge with Linux 2.4.0-test5-pre4.
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Makefile6
-rw-r--r--arch/sh/boot/compressed/Makefile6
-rw-r--r--arch/sh/boot/compressed/misc.c20
-rw-r--r--arch/sh/config.in13
-rw-r--r--arch/sh/defconfig23
-rw-r--r--arch/sh/kernel/Makefile4
-rw-r--r--arch/sh/kernel/cf-enabler.c2
-rw-r--r--arch/sh/kernel/entry.S37
-rw-r--r--arch/sh/kernel/io_generic.c22
-rw-r--r--arch/sh/kernel/irq.c6
-rw-r--r--arch/sh/kernel/process.c2
-rw-r--r--arch/sh/kernel/setup.c90
-rw-r--r--arch/sh/kernel/setup_se.c9
-rw-r--r--arch/sh/kernel/sh_bios.c70
-rw-r--r--arch/sh/kernel/sh_ksyms.c7
-rw-r--r--arch/sh/kernel/signal.c1
-rw-r--r--arch/sh/kernel/time.c23
-rw-r--r--arch/sh/mm/cache.c10
-rw-r--r--arch/sh/mm/fault.c43
-rw-r--r--arch/sh/mm/init.c5
-rw-r--r--arch/sh/vmlinux.lds.S12
21 files changed, 350 insertions, 61 deletions
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 05cc37101..7be14e899 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -15,9 +15,9 @@
#
# Select the object file format to substitute into the linker script.
#
-tool-prefix = sh-linux-gnu-
+tool_prefix = sh-linux-gnu-
-ifdef CONFIG_LITTLE_ENDIAN
+ifdef CONFIG_CPU_LITTLE_ENDIAN
CFLAGS += -ml
AFLAGS += -ml
# LINKFLAGS += -EL
@@ -30,7 +30,7 @@ LDFLAGS := -EB
endif
# ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE = $(tool-prefix)
+CROSS_COMPILE = $(tool_prefix)
# endif
LD =$(CROSS_COMPILE)ld $(LDFLAGS)
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 7a5b5b22f..d62db2722 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -9,12 +9,16 @@ SYSTEM = $(TOPDIR)/vmlinux
OBJECTS = $(HEAD) misc.o
+ifdef CONFIG_SH_STANDARD_BIOS
+OBJECTS += ../../kernel/sh_bios.o
+endif
+
ZLDFLAGS = -e startup -T $(TOPDIR)/arch/sh/vmlinux.lds
#
# ZIMAGE_OFFSET is the load offset of the compression loader
#
-ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000])
+ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000+0x10000+0x400])
ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
index aab798505..a2da3fe75 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc.c
@@ -7,10 +7,15 @@
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
*/
#include <linux/config.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_SH_STANDARD_BIOS
+#include <asm/sh_bios.h>
+#endif
/*
* gzip declarations
@@ -128,12 +133,7 @@ static void gzip_release(void **ptr)
free_mem_ptr = (long) *ptr;
}
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
-#define IN_GDB 1
-#endif
-#include <asm/io.h>
-#include "../../../../drivers/char/sh-sci.h"
-
+#ifdef CONFIG_SH_STANDARD_BIOS
static int strlen(const char *s)
{
int i = 0;
@@ -145,8 +145,14 @@ static int strlen(const char *s)
void puts(const char *s)
{
- put_string(s, strlen(s));
+ sh_bios_console_write(s, strlen(s));
}
+#else
+void puts(const char *s)
+{
+ /* This should be updated to use the sh-sci routines */
+}
+#endif
void* memset(void* s, int c, size_t n)
{
diff --git a/arch/sh/config.in b/arch/sh/config.in
index 0a83038dc..2d0790bde 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -46,7 +46,7 @@ if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then
define_bool CONFIG_CPU_SH3 n
define_bool CONFIG_CPU_SH4 y
fi
-bool 'Little Endian' CONFIG_LITTLE_ENDIAN
+bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
"$CONFIG_SH_OVERDRIVE" = "y" ]; then
define_hex CONFIG_MEMORY_START 0c000000
@@ -168,8 +168,9 @@ if [ "$CONFIG_VT" = "y" ]; then
bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE
fi
-tristate 'Serial support' CONFIG_SERIAL
-if [ "$CONFIG_SERIAL" = "y" ]; then
+tristate 'Serial (8250, 16450, 16550 or compatible) support' CONFIG_SERIAL
+tristate 'Serial (SCI, SCIF) support' CONFIG_SH_SCI
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SH_SCI" = "y" ]; then
bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
fi
comment 'Unix 98 PTY support'
@@ -218,5 +219,9 @@ mainmenu_option next_comment
comment 'Kernel hacking'
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+bool 'Use LinuxSH standard BIOS' CONFIG_SH_STANDARD_BIOS
+if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then
+ bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+ bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
+fi
endmenu
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index be2685bd7..e1d9d1725 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -10,6 +10,11 @@ CONFIG_UID16=y
# CONFIG_EXPERIMENTAL is not set
#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
# Processor type and features
#
CONFIG_SH_GENERIC=y
@@ -21,16 +26,11 @@ CONFIG_CPU_SUBTYPE_SH7708=y
# CONFIG_CPU_SUBTYPE_SH7750 is not set
CONFIG_CPU_SH3=y
# CONFIG_CPU_SH4 is not set
-CONFIG_LITTLE_ENDIAN=y
+CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_MEMORY_START=0c000000
CONFIG_IOPORT_START=ba000000
#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
# General setup
#
# CONFIG_ISA is not set
@@ -55,6 +55,11 @@ CONFIG_BINFMT_ELF=y
# CONFIG_PARPORT is not set
#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
@@ -126,7 +131,8 @@ CONFIG_BLK_DEV_IDEDISK=y
# Character devices
#
# CONFIG_VT is not set
-CONFIG_SERIAL=y
+# CONFIG_SERIAL is not set
+CONFIG_SH_SCI=y
CONFIG_SERIAL_CONSOLE=y
#
@@ -150,6 +156,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -191,4 +198,6 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_SH_STANDARD_BIOS=y
CONFIG_DEBUG_KERNEL_WITH_GDB_STUB=y
+CONFIG_SH_EARLY_PRINTK=y
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 95b6c5f13..7b3852295 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -44,6 +44,10 @@ ifdef CONFIG_HD64461
O_OBJS += setup_hd64461.o
endif
+ifdef CONFIG_SH_STANDARD_BIOS
+O_OBJS += sh_bios.o
+endif
+
all: kernel.o head.o init_task.o
entry.o: entry.S
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index d5c7437ae..3727c7264 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -84,7 +84,7 @@ int __init cf_init(void)
int __init cf_init(void)
{
/* Enable the card, and set the level interrupt */
- outw(0x0042, CF_CIS_BASE+0x0200);
+ ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
make_imask_irq(14);
disable_irq(14);
return 0;
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index e54c37b09..cbca87e69 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -52,7 +52,7 @@
flags = 4
sigpending = 8
need_resched = 20
-tsk_ptrace = 60
+tsk_ptrace = 24
PT_TRACESYS = 0x00000002
PF_USEDFPU = 0x00100000
@@ -275,12 +275,26 @@ ENTRY(ret_from_fork)
* Arguments #4 to #6: R0, R1, R2
* TRA: (number of arguments + 0x10) x 4
*
+ * This code also handles delegating other traps to the BIOS/gdb stub
+ * according to:
+ *
+ * Trap number
+ * (TRA>>2) Purpose
+ * -------- -------
+ * 0x0-0xf old syscall ABI
+ * 0x10-0x1f new syscall ABI
+ * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
+ *
+ * Note: When we're first called, the TRA value must be shifted
+ * right 2 bits in order to get the value that was used as the "trapa"
+ * argument.
*/
system_call:
mov.l 1f, $r9
mov.l @$r9, $r8
!
+ ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
mov #0x20, $r9
extu.b $r9, $r9
shll2 $r9
@@ -531,9 +545,9 @@ restore_all:
shlr2 $k0
and #0x3c, $k0
cmp/eq #0x3c, $k0
- bf/s 7f
- mov $g_imask, $k0
- shll2 $k0
+ bt/s 7f
+ shll2 $k0
+ mov $g_imask, $k0
!
7: or $k0, $k2 ! Set the IMASK-bits
ldc $k2, $ssr
@@ -648,19 +662,20 @@ handle_exception:
! save all registers onto stack.
!
stc $ssr, $k0 ! from kernel space?
- shll $k0 ! Check MD bit (bit30)
+ shll $k0 ! Check MD bit (bit30) by shifting it into the T bit
shll $k0
#if defined(__SH4__)
bf/s 8f ! it's from user to kernel transition
mov $r15, $k0 ! save original stack to k0
- /* Kernel to kernel transition */
+ /* It's a kernel to kernel transition. */
+ /* Is the FPU disabled? */
mov.l 2f, $k1
stc $ssr, $k0
tst $k1, $k0
mov.l 4f, $k1
- bf/s 9f ! FPU is not used
+ bf/s 9f ! FPU is not enabled, no need to save it
mov $r15, $k0 ! save original stack to k0
- ! FPU is used, save FPU
+ ! FPU is enabled, save it
! /* XXX: Need to save another bank of FPU if all FPU feature is used */
! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */
sts.l $fpul, @-$r15
@@ -687,7 +702,7 @@ handle_exception:
fmov.s $fr0, @-$r15
#else
mov.l 3f, $k1
- bt/s 9f ! it's from kernel to kernel transition
+ bt/s 9f ! it's a kernel to kernel transition, and skip the FPU save.
mov $r15, $k0 ! save original stack to k0 anyway
#endif
8: /* User space to kernel */
@@ -697,7 +712,9 @@ handle_exception:
mov $k1, $r15 ! change to kernel stack
!
mov.l 4f, $k1 ! let kernel release FPU
-9: mov #-1, $k4
+9: ! Save the user registers on the stack.
+ ! At this point, k1 should have been set to the new SR value
+ mov #-1, $k4
mov.l $k4, @-$r15 ! syscall_nr (default: -1)
!
sts.l $macl, @-$r15
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 2465bc28c..1faa01ce3 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -6,11 +6,21 @@
*
* Generic I/O routine.
*
+ * 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.
+ *
*/
#include <linux/config.h>
#include <asm/io.h>
+#if defined(__sh3__)
+/* I'm not sure SH7709 has this kind of bug */
+#define SH3_PCMCIA_BUG_WORKAROUND 1
+#define DUMMY_READ_AREA6 0xba000000
+#endif
+
#define PORT2ADDR(x) (CONFIG_IOPORT_START+(x))
static inline void delay(void)
@@ -51,12 +61,18 @@ void insw(unsigned int port, void *buffer, unsigned long count)
{
unsigned short *buf=buffer;
while(count--) *buf++=inw(port);
+#ifdef SH3_PCMCIA_BUG_WORKAROUND
+ ctrl_inb (DUMMY_READ_AREA6);
+#endif
}
void insl(unsigned int port, void *buffer, unsigned long count)
{
unsigned long *buf=buffer;
while(count--) *buf++=inl(port);
+#ifdef SH3_PCMCIA_BUG_WORKAROUND
+ ctrl_inb (DUMMY_READ_AREA6);
+#endif
}
void outb(unsigned long b, unsigned int port)
@@ -90,10 +106,16 @@ void outsw(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned short *buf=buffer;
while(count--) outw(*buf++, port);
+#ifdef SH3_PCMCIA_BUG_WORKAROUND
+ ctrl_inb (DUMMY_READ_AREA6);
+#endif
}
void outsl(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned long *buf=buffer;
while(count--) outl(*buf++, port);
+#ifdef SH3_PCMCIA_BUG_WORKAROUND
+ ctrl_inb (DUMMY_READ_AREA6);
+#endif
}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index f21d0e451..399d435af 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -41,8 +41,8 @@
#include <asm/hd64461.h>
#endif
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
+unsigned int __local_bh_count[NR_CPUS];
+unsigned int __local_irq_count[NR_CPUS];
/*
* Micro-access to controllers is serialized over the whole
@@ -183,7 +183,7 @@ void disable_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- if (!local_irq_count[smp_processor_id()]) {
+ if (!__local_irq_count[smp_processor_id()]) {
do {
barrier();
} while (irq_desc[irq].status & IRQ_INPROGRESS);
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6a949883c..60205379c 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -331,7 +331,6 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
int error;
char *filename;
- lock_kernel();
filename = getname(ufilename);
error = PTR_ERR(filename);
if (IS_ERR(filename))
@@ -342,7 +341,6 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index c8c04ec12..69988d873 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -37,7 +37,10 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/smp.h>
-
+#ifdef CONFIG_SH_EARLY_PRINTK
+#include <linux/console.h>
+#include <asm/sh_bios.h>
+#endif
/*
* Machine setup..
@@ -101,14 +104,83 @@ static struct resource ram_resources[] = {
{ "Kernel data", 0, 0 }
};
-/* System ROM resources */
-#define MAXROMS 6
-static struct resource rom_resources[MAXROMS] = {
- { "System ROM", 0xF0000, 0xFFFFF, IORESOURCE_BUSY },
- { "Video ROM", 0xc0000, 0xc7fff }
+static unsigned long memory_start, memory_end;
+
+#ifdef CONFIG_SH_EARLY_PRINTK
+/*
+ * Print a string through the BIOS
+ */
+static void sh_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ sh_bios_console_write(s, count);
+}
+
+/*
+ * Receive character from the serial port
+ */
+static int sh_console_wait_key(struct console *co)
+{
+ /* Not implemented yet */
+ return 0;
+}
+
+static kdev_t sh_console_device(struct console *c)
+{
+ /* TODO: this is totally bogus */
+ /* return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index); */
+ return 0;
+}
+
+/*
+ * Setup initial baud/bits/parity. We do two things here:
+ * - construct a cflag setting for the first rs_open()
+ * - initialize the serial port
+ * Return non-zero if we didn't find a serial port.
+ */
+static int __init sh_console_setup(struct console *co, char *options)
+{
+ int cflag = CREAD | HUPCL | CLOCAL;
+
+ /*
+ * Now construct a cflag setting.
+ * TODO: this is a totally bogus cflag, as we have
+ * no idea what serial settings the BIOS is using, or
+ * even if its using the serial port at all.
+ */
+ cflag |= B115200 | CS8 | /*no parity*/0;
+
+ co->cflag = cflag;
+
+ return 0;
+}
+
+static struct console sh_console = {
+ "bios",
+ sh_console_write,
+ NULL,
+ sh_console_device,
+ sh_console_wait_key,
+ NULL,
+ sh_console_setup,
+ CON_PRINTBUFFER,
+ -1,
+ 0,
+ NULL
};
-static unsigned long memory_start, memory_end;
+void sh_console_init(void)
+{
+ register_console(&sh_console);
+}
+
+void sh_console_unregister(void)
+{
+ unregister_console(&sh_console);
+}
+
+#endif
+
static inline void parse_mem_cmdline (char ** cmdline_p)
{
@@ -153,6 +225,10 @@ void __init setup_arch(char **cmdline_p)
unsigned long bootmap_size;
unsigned long start_pfn, max_pfn, max_low_pfn;
+#ifdef CONFIG_SH_EARLY_PRINTK
+ sh_console_init();
+#endif
+
ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/arch/sh/kernel/setup_se.c b/arch/sh/kernel/setup_se.c
index bcb9b6414..cd9436fff 100644
--- a/arch/sh/kernel/setup_se.c
+++ b/arch/sh/kernel/setup_se.c
@@ -52,6 +52,13 @@ static void __init init_smsc(void)
smsc_config(ACTIVATE_INDEX, 0x01);
smsc_config(IO_BASE_HI_INDEX, 0x03);
smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+ /* COM2 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x02);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
/* RTC */
@@ -59,7 +66,7 @@ static void __init init_smsc(void)
smsc_config(ACTIVATE_INDEX, 0x01);
smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
- /* XXX: COM2, PARPORT, KBD, and MOUSE will come here... */
+ /* XXX: PARPORT, KBD, and MOUSE will come here... */
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
new file mode 100644
index 000000000..9c6b107a6
--- /dev/null
+++ b/arch/sh/kernel/sh_bios.c
@@ -0,0 +1,70 @@
+/* $Id$
+ *
+ * linux/arch/sh/kernel/sh_bios.c
+ * C interface for trapping into the standard LinuxSH BIOS.
+ *
+ * Copyright (C) 2000 Greg Banks, Mitch Davis
+ *
+ */
+
+#include <config/sh/standard/bios.h>
+#include <asm/sh_bios.h>
+
+#ifdef CONFIG_SH_STANDARD_BIOS
+
+#define BIOS_CALL_CONSOLE_WRITE 0
+#define BIOS_CALL_READ_BLOCK 1 /* not implemented */
+#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
+#define BIOS_CALL_GDB_GET_MODE_PTR 0xfe
+#define BIOS_CALL_GDB_DETACH 0xff
+
+static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3)
+{
+ register long r0 __asm__("$r0") = func;
+ register long r4 __asm__("$r4") = arg0;
+ register long r5 __asm__("$r5") = arg1;
+ register long r6 __asm__("$r6") = arg2;
+ register long r7 __asm__("$r7") = arg3;
+ __asm__ __volatile__("trapa #0x3f"
+ : "=z" (r0)
+ : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7)
+ : "memory");
+ return r0;
+}
+
+
+void sh_bios_console_write(const char *buf, unsigned int len)
+{
+ sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
+}
+
+
+void sh_bios_char_out(char ch)
+{
+ sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
+}
+
+
+int sh_bios_in_gdb_mode(void)
+{
+ static char queried = 0;
+ static char *gdb_mode_p = 0;
+
+ if (!queried)
+ {
+ /* Query the gdb stub for address of its gdb mode variable */
+ long r = sh_bios_call(BIOS_CALL_GDB_GET_MODE_PTR, 0, 0, 0, 0);
+ if (r != ~0) /* BIOS returns -1 for unknown function */
+ gdb_mode_p = (char *)r;
+ queried = 1;
+ }
+ return (gdb_mode_p != 0 ? *gdb_mode_p : 0);
+}
+
+void sh_bios_gdb_detach(void)
+{
+ sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
+}
+
+#endif
+
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 2b1b9ea2e..73d971982 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -21,17 +21,10 @@
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
/* platform dependent support */
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(local_bh_count);
-EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(kernel_thread);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 65469f7e1..221af3022 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -669,7 +669,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* FALLTHRU */
default:
- lock_kernel();
sigaddset(&current->signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 3861fec7d..2c73255f4 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -114,18 +114,18 @@
#endif
extern rwlock_t xtime_lock;
+extern unsigned long wall_jiffies;
#define TICK_SIZE tick
void do_gettimeofday(struct timeval *tv)
{
- extern volatile unsigned long lost_ticks;
unsigned long flags;
unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
usec = 0;
{
- unsigned long lost = lost_ticks;
+ unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
@@ -142,9 +142,28 @@ void do_gettimeofday(struct timeval *tv)
tv->tv_usec = usec;
}
+/*
+ * Could someone please implement this...
+ */
+#define do_gettimeoffset() 0
+
void do_settimeofday(struct timeval *tv)
{
write_lock_irq(&xtime_lock);
+ /*
+ * This is revolting. We need to set "xtime" correctly. However, the
+ * value in this location is the value at the most recent update of
+ * wall time. Discover what correction gettimeofday() would have
+ * made, and then undo it!
+ */
+ tv->tv_usec -= do_gettimeoffset();
+ tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
+
+ while (tv->tv_usec < 0) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec--;
+ }
+
xtime = *tv;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 895681fc6..56f444bf4 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -2,7 +2,7 @@
*
* linux/arch/sh/mm/cache.c
*
- * Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 1999, 2000 Niibe Yutaka
*
*/
@@ -36,7 +36,10 @@ struct _cache_system_info {
int num_entries;
};
-static struct _cache_system_info cache_system_info;
+/* Data at BSS is cleared after setting this variable.
+ So, we Should not placed this variable at BSS section.
+ Initialize this, it is placed at data section. */
+static struct _cache_system_info cache_system_info = {0,};
#define CACHE_OC_WAY_SHIFT (cache_system_info.way_shift)
#define CACHE_IC_WAY_SHIFT (cache_system_info.way_shift)
@@ -97,7 +100,7 @@ static inline void cache_wback_all(void)
}
}
-static void
+static void __init
detect_cpu_and_cache_system(void)
{
#if defined(__sh3__)
@@ -338,6 +341,7 @@ void flush_cache_range(struct mm_struct *mm, unsigned long start,
void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
{
+ /* XXX: Umm... this flush out all the cache lines. Any improvement? */
flush_cache_range(vma->vm_mm, addr, addr+PAGE_SIZE);
}
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 428bec21c..9dd6ae451 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -29,6 +29,9 @@
extern void die(const char *,struct pt_regs *,long);
static void __flush_tlb_page(struct mm_struct *mm, unsigned long page);
+#if defined(__SH4__)
+static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys);
+#endif
/*
* Ugly, ugly, but the goto's result in better assembly..
@@ -277,6 +280,19 @@ void update_mmu_cache(struct vm_area_struct * vma,
save_and_cli(flags);
+#if defined(__SH4__)
+ if ((vma->vm_flags & VM_SHARED)) {
+ pteval = pte_val(pte);
+ pteval &= PAGE_MASK; /* Physicall page address */
+
+ __flush_tlb_phys(vma->vm_mm, pteval);
+
+ /* It would be good we had routine which takes
+ physical memory as argument */
+ flush_cache_page(vma, address&PAGE_MASK);
+ }
+#endif
+
/* Set PTEH register */
if (vma) {
pteaddr = (address & MMU_VPN_MASK) |
@@ -328,6 +344,33 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
set_asid(saved_asid);
}
+#if defined(__SH4__)
+static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys)
+{
+ int i;
+ unsigned long addr, data;
+
+ jump_to_P2();
+ for (i = 0; i < MMU_UTLB_ENTRIES; i++) {
+ addr = MMU_UTLB_DATA_ARRAY | (i<<MMU_U_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & MMU_UTLB_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~MMU_UTLB_VALID;
+ ctrl_outl(data, addr);
+ }
+ }
+ for (i = 0; i < MMU_ITLB_ENTRIES; i++) {
+ addr = MMU_ITLB_DATA_ARRAY | (i<<MMU_I_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & MMU_ITLB_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~MMU_ITLB_VALID;
+ ctrl_outl(data, addr);
+ }
+ }
+ back_to_P1();
+}
+#endif
+
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
unsigned long flags;
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 931564cac..f798ef968 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.16 2000/02/14 15:19:05 gniibe Exp $
+/* $Id: init.c,v 1.17 2000-04-08 15:38:54+09 gniibe Exp $
*
* linux/arch/sh/mm/init.c
*
@@ -207,6 +207,9 @@ void __init paging_init(void)
/* Enable MMU */
ctrl_outl(MMU_CONTROL_INIT, MMUCR);
+ /* The manual suggests doing some nops after turning on the MMU */
+ asm volatile("nop;nop;nop;nop;nop;nop;");
+
mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index 736e4301f..1a7c2e820 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -3,7 +3,7 @@
* Written by Niibe Yutaka
*/
#include <linux/config.h>
-#ifdef CONFIG_LITTLE_ENDIAN
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
#else
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
@@ -78,6 +78,16 @@ SECTIONS
. = ALIGN(4);
_end = . ;
+ /* When something in the kernel is NOT compiled as a module, the
+ * module cleanup code and data are put into these segments. Both
+ * can then be thrown away, as cleanup code is never called unless
+ * it's a module.
+ */
+ /DISCARD/ : {
+ *(.text.exit)
+ *(.data.exit)
+ }
+
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }