diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-23 14:05:01 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-23 14:05:01 +0000 |
commit | f3627cbe9236a062012c836f3b6ee311b43f63f2 (patch) | |
tree | ae854838b9a73b35bd0f3b8f42e5fb7f9cb1d5a9 /arch | |
parent | fea12a7b3f20bc135ab533491411e9ff753c01c8 (diff) |
Merge with Linux 2.4.0-test5-pre4.
Diffstat (limited to 'arch')
30 files changed, 364 insertions, 72 deletions
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index b99d0cec3..1055ed5e3 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -481,6 +481,10 @@ CONFIG_PSMOUSE=y CONFIG_DRM=y CONFIG_DRM_TDFX=y # CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_I810 is not set +# CONFIG_DRM_MGA is not set +# CONFIG_AGP is not set CONFIG_PCMCIA_SERIAL=y # diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index b1debd5fe..039ba695c 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -1423,6 +1423,8 @@ static int apm(void *unused) kapmd_running = 1; exit_files(current); /* daemonize doesn't do exit_files */ + current->files = init_task.files; + atomic_inc(¤t->files->count); daemonize(); strcpy(current->comm, "kapmd"); diff --git a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt index dc709bf16..bfef9e3a0 100644 --- a/arch/mips/defconfig-cobalt +++ b/arch/mips/defconfig-cobalt @@ -448,7 +448,6 @@ CONFIG_RTC=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set # diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion index d9a78da25..e45b978b4 100644 --- a/arch/mips/defconfig-orion +++ b/arch/mips/defconfig-orion @@ -203,7 +203,6 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set # diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200 index 5b71797a8..f67154e91 100644 --- a/arch/mips/defconfig-rm200 +++ b/arch/mips/defconfig-rm200 @@ -234,7 +234,6 @@ CONFIG_RTC=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set # diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 3af288cff..aa9fdef16 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -327,7 +327,7 @@ CONFIG_SERIAL_CONSOLE=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set +# CONFIG_AGP is not set # # File systems diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 index a40dc4eb0..6c2835d21 100644 --- a/arch/mips64/defconfig-ip22 +++ b/arch/mips64/defconfig-ip22 @@ -246,7 +246,7 @@ CONFIG_VT_CONSOLE=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set +# CONFIG_AGP is not set # # File systems diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index 3af288cff..aa9fdef16 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -327,7 +327,7 @@ CONFIG_SERIAL_CONSOLE=y # # CONFIG_FTAPE is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set +# CONFIG_AGP is not set # # File systems 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(¤t->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) } diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index c424722a5..795960fea 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1085,7 +1085,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { struct floppy_struct *f; - f = karg = kmalloc(GFP_KERNEL, sizeof(struct floppy_struct)); + f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETPRM32) @@ -1111,7 +1111,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { struct floppy_drive_params *f; - f = karg = kmalloc(GFP_KERNEL, sizeof(struct floppy_drive_params)); + f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETDRVPRM32) @@ -1143,17 +1143,17 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: - karg = kmalloc(GFP_KERNEL, sizeof(struct floppy_drive_struct)); + karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDGETFDCSTAT32: - karg = kmalloc(GFP_KERNEL, sizeof(struct floppy_fdc_state)); + karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDWERRORGET32: - karg = kmalloc(GFP_KERNEL, sizeof(struct floppy_write_errors)); + karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL); if (!karg) return -ENOMEM; break; |