diff options
Diffstat (limited to 'arch')
53 files changed, 1529 insertions, 301 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 039ba695c..9a4084292 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -410,7 +410,7 @@ static const lookup_t error_table[] = { #ifndef CONFIG_APM_ALLOW_INTS # define APM_DO_CLI __cli() #else -# define APM_DO_CLI +# define APM_DO_CLI __sti() #endif #ifdef APM_ZERO_SEGS # define APM_DECL_SEGS \ diff --git a/arch/i386/lib/memcpy.c b/arch/i386/lib/memcpy.c new file mode 100644 index 000000000..4cb37b6e5 --- /dev/null +++ b/arch/i386/lib/memcpy.c @@ -0,0 +1,19 @@ +#include <linux/config.h> +#include <linux/string.h> + +#undef memcpy +#undef memset + +void * memcpy(void * to, const void * from, size_t n) +{ +#ifdef CONFIG_X86_USE_3DNOW + return __memcpy3d(to, from, n); +#else + return __memcpy(to, from, n); +#endif +} + +void * memset(void * s, int c, size_t count) +{ + return __memset(s, c, count); +} diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index 051364fe3..29891e47a 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -129,9 +129,9 @@ static void __init sgi_irq_setup(void) int __init page_is_ram(unsigned long pagenr) { - if (pagenr < MAP_NR(PAGE_OFFSET + 0x2000UL)) + if ((pagenr<<PAGE_SHIFT) < 0x2000UL) return 1; - if (pagenr > MAP_NR(PAGE_OFFSET + 0x08002000)) + if ((pagenr<<PAGE_SHIFT) > 0x08002000) return 1; return 0; } diff --git a/arch/mips64/sgi-ip22/ip22-setup.c b/arch/mips64/sgi-ip22/ip22-setup.c index 937d291d1..a0f429429 100644 --- a/arch/mips64/sgi-ip22/ip22-setup.c +++ b/arch/mips64/sgi-ip22/ip22-setup.c @@ -114,9 +114,9 @@ struct kbd_ops sgi_kbd_ops = { int __init page_is_ram(unsigned long pagenr) { - if (pagenr < MAP_NR(PAGE_OFFSET + 0x2000UL)) + if ((pagenr<<PAGE_SHIFT) < 0x2000UL) return 1; - if (pagenr > MAP_NR(PAGE_OFFSET + 0x08002000)) + if ((pagenr<<PAGE_SHIFT) > 0x08002000) return 1; return 0; } diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index d62db2722..bd419991b 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -18,7 +18,7 @@ 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+0x10000+0x400]) +ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000+0x10000]) ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS) diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S index d270d1b47..86a3acf82 100644 --- a/arch/sh/boot/compressed/head.S +++ b/arch/sh/boot/compressed/head.S @@ -10,6 +10,9 @@ .global startup startup: + /* Load initial status register */ + mov.l init_sr, r1 + ldc r1, sr /* First clear BSS */ mov.l end_addr, r1 @@ -20,10 +23,6 @@ l1: cmp/eq r1,r2 bf l1 - /* Load initial status register */ - mov.l init_sr, r1 - ldc r1, sr - /* Set the initial pointer. */ mov.l init_stack_addr, r0 mov.l @r0, r15 @@ -44,7 +43,7 @@ bss_start_addr: end_addr: .long _end init_sr: - .long 0x50000000 /* Privileged mode, Bank=0, Block=1, I3-I0=0 */ + .long 0x40000000 /* Privileged mode, Bank=0, Block=0, I3-I0=0 */ init_stack_addr: .long stack_start decompress_kernel_addr: diff --git a/arch/sh/config.in b/arch/sh/config.in index 2d0790bde..fa36d92f7 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -28,12 +28,19 @@ choice 'SuperH system type' \ "Generic CONFIG_SH_GENERIC \ SolutionEngine CONFIG_SH_SOLUTION_ENGINE \ Overdrive CONFIG_SH_OVERDRIVE \ - HP600 CONFIG_SH_HP600" Generic + HP600 CONFIG_SH_HP600 \ + CqREEK CONFIG_SH_CQREEK \ + BareCPU CONFIG_SH_UNKNOWN" Generic choice 'Processor type' \ - "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ + "SH7707 CONFIG_CPU_SUBTYPE_SH7707 \ + SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708 +if [ "$CONFIG_CPU_SUBTYPE_SH7707" = "y" ]; then + define_bool CONFIG_CPU_SH3 y + define_bool CONFIG_CPU_SH4 n +fi if [ "$CONFIG_CPU_SUBTYPE_SH7708" = "y" ]; then define_bool CONFIG_CPU_SH3 y define_bool CONFIG_CPU_SH4 n @@ -52,7 +59,6 @@ if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \ define_hex CONFIG_MEMORY_START 0c000000 else hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 - hex 'I/O port offset address' CONFIG_IOPORT_START ba000000 fi endmenu @@ -178,6 +184,12 @@ bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi + +if [ "$CONFIG_SH_GENERIC" = "y" -o \ + "$CONFIG_SH_OVERDRIVE" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then + bool 'Heartbeat LED' CONFIG_HEARTBEAT +fi + if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT if [ "$CONFIG_PRINTER" != "n" ]; then @@ -221,7 +233,8 @@ comment 'Kernel hacking' bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ 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 + hex ' GDB Stub VBR' CONFIG_GDB_STUB_VBR a0000000 + 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 e1d9d1725..5ffc0e0ab 100644 --- a/arch/sh/defconfig +++ b/arch/sh/defconfig @@ -21,6 +21,8 @@ CONFIG_SH_GENERIC=y # CONFIG_SH_SOLUTION_ENGINE is not set # CONFIG_SH_OVERDRIVE is not set # CONFIG_SH_HP600 is not set +# CONFIG_SH_UNKNOWN is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set CONFIG_CPU_SUBTYPE_SH7708=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set @@ -28,7 +30,6 @@ CONFIG_CPU_SH3=y # CONFIG_CPU_SH4 is not set CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_MEMORY_START=0c000000 -CONFIG_IOPORT_START=ba000000 # # General setup @@ -139,6 +140,7 @@ CONFIG_SERIAL_CONSOLE=y # Unix 98 PTY support # # CONFIG_UNIX98_PTYS is not set +# CONFIG_HEARTBEAT is not set # # File systems @@ -200,4 +202,5 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_MAGIC_SYSRQ is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_DEBUG_KERNEL_WITH_GDB_STUB=y +CONFIG_GDB_STUB_VBR=a0000000 CONFIG_SH_EARLY_PRINTK=y diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 7b3852295..c9de70daf 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -11,8 +11,8 @@ O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ - ptrace.o setup.o time.o sys_sh.o semaphore.o pci-sh.o \ - irq_imask.o + ptrace.o setup.o time.o sys_sh.o semaphore.o \ + irq_imask.o io.o OX_OBJS := sh_ksyms.o MX_OBJS := @@ -21,26 +21,45 @@ O_OBJS += cf-enabler.o endif ifdef CONFIG_SH_GENERIC + +O_OBJS += mach_se.o setup_se.o setup_cqreek.o io_se.o led_se.o \ + mach_hp600.o io_hd64461.o \ + mach_unknown.o io_unknown.o \ + io_generic.o + +else + +ifdef CONFIG_SH_HP600 +O_OBJS += mach_hp600.o io_hd64461.o io_generic.o +endif + +ifdef CONFIG_SH_OVERDRIVE O_OBJS += io_generic.o endif ifdef CONFIG_SH_SOLUTION_ENGINE -O_OBJS += setup_se.o io_se.o +O_OBJS += mach_se.o setup_se.o io_se.o io_generic.o led_se.o endif -ifdef CONFIG_SH_OVERDRIVE -O_OBJS += setup_od.o io_generic.o +ifdef CONFIG_SH_CQREEK +O_OBJS += setup_cqreek.o +endif + +ifdef CONFIG_SH_UNKNOWN +O_OBJS += mach_unknown.o io_unknown.o io_generic.o endif -ifdef CONFIG_SH_HP600 -O_OBJS += io_hd64461.o endif ifdef CONFIG_CPU_SH4 O_OBJS += fpu.o endif -ifdef CONFIG_HD64461 +ifdef CONFIG_PCI +O_OBJS += pci-sh.o +endif + +ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_HD64461),) O_OBJS += setup_hd64461.o endif diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index 3727c7264..c446a1151 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c @@ -14,15 +14,18 @@ #include <asm/io.h> #include <asm/irq.h> -#ifdef CONFIG_SH_SOLUTION_ENGINE #include <asm/hitachi_se.h> + + /* + * SolutionEngine + * * 0xB8400000 : Common Memory * 0xB8500000 : Attribute * 0xB8600000 : I/O */ -int __init cf_init(void) +static int __init cf_init_se(void) { if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0) return 0; /* Not detected */ @@ -68,11 +71,15 @@ int __init cf_init(void) ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200); return 0; } -#else /* then generic system type */ + #define CF_CIS_BASE 0xb8000000 /* * You can connect Compact Flash directly to the bus of SuperH. * This is the enabler for that. + * + * SIM: How generic is this really? It looks pretty board, or at + * least SH sub-type, specific to me. + * I know it doesn't work on the Overdrive! */ /* @@ -81,7 +88,7 @@ int __init cf_init(void) * 0xBA000000 : I/O */ -int __init cf_init(void) +static int __init cf_init_default(void) { /* Enable the card, and set the level interrupt */ ctrl_outw(0x0042, CF_CIS_BASE+0x0200); @@ -89,6 +96,13 @@ int __init cf_init(void) disable_irq(14); return 0; } -#endif + +int __init cf_init(void) +{ + if (MACH_SE) { + return cf_init_se(); + } + return cf_init_default(); +} __initcall (cf_init); diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 450d49824..4e57175e7 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -62,7 +62,7 @@ ENOSYS = 38 #if defined(__sh3__) TRA = 0xffffffd0 EXPEVT = 0xffffffd4 -#ifdef CONFIG_CPU_SUBTYPE_SH7709 +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000) #else INTEVT = 0xffffffd8 @@ -182,7 +182,7 @@ tlb_protection_violation_store: 1: .long SYMBOL_NAME(do_page_fault) 2: .long MMU_TEA -#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB +#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS) .align 2 /* Unwind the stack and jmp to the debug entry */ debug_kernel: @@ -219,12 +219,12 @@ debug_kernel: ldc $k1, $ssr .align 2 1: .long 0x300000f0 -2: .long 0xa0000100 +2: .long CONFIG_GDB_STUB_VBR + 0x100 #endif .align 2 debug_trap: -#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB +#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS) mov #SR, $r0 mov.l @($r0,$r15), $r0 ! get status register shll $r0 @@ -829,7 +829,7 @@ ENTRY(interrupt_table) .long SYMBOL_NAME(do_IRQ) ! rovi .long SYMBOL_NAME(do_IRQ) .long SYMBOL_NAME(do_IRQ) -#if defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) .long SYMBOL_NAME(do_IRQ) ! 32 IRQ irq0 .long SYMBOL_NAME(do_IRQ) ! 33 irq1 .long SYMBOL_NAME(do_IRQ) ! 34 irq2 @@ -859,6 +859,11 @@ ENTRY(interrupt_table) .long SYMBOL_NAME(do_IRQ) ! 58 bri2 .long SYMBOL_NAME(do_IRQ) ! 59 txi2 .long SYMBOL_NAME(do_IRQ) ! 60 ADC adi +#if defined(CONFIG_CPU_SUBTYPE_SH7707) + .long SYMBOL_NAME(do_IRQ) ! 61 LCDC lcdi + .long SYMBOL_NAME(do_IRQ) ! 62 PCC pcc0i + .long SYMBOL_NAME(do_IRQ) ! 63 pcc1i +#endif #elif defined(__SH4__) .long SYMBOL_NAME(do_IRQ) ! Hitachi UDI .long SYMBOL_NAME(do_IRQ) ! GPIO diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c new file mode 100644 index 000000000..27f250f9f --- /dev/null +++ b/arch/sh/kernel/io.c @@ -0,0 +1,202 @@ +/* + * linux/arch/sh/kernel/io_generic.c + * + * Copyright (C) 2000 Stuart Menefy + * + * Provide real functions which expand to whatever the header file defined. + * Also definitions of machine independant IO functions. + */ + +#include <linux/config.h> +#include <asm/io.h> + +unsigned int _inb(unsigned long port) +{ + return __inb(port); +} + +unsigned int _inw(unsigned long port) +{ + return __inw(port); +} + +unsigned int _inl(unsigned long port) +{ + return __inl(port); +} + +void _outb(unsigned char b, unsigned long port) +{ + __outb(b, port); +} + +void _outw(unsigned short b, unsigned long port) +{ + __outw(b, port); +} + +void _outl(unsigned int b, unsigned long port) +{ + __outl(b, port); +} + +unsigned int _inb_p(unsigned long port) +{ + return __inb_p(port); +} + +unsigned int _inw_p(unsigned long port) +{ + return __inw_p(port); +} + +void _outb_p(unsigned char b, unsigned long port) +{ + __outb_p(b, port); +} + +void _outw_p(unsigned short b, unsigned long port) +{ + __outw_p(b, port); +} + +void _insb(unsigned long port, void *buffer, unsigned long count) +{ + return __insb(port, buffer, count); +} + +void _insw(unsigned long port, void *buffer, unsigned long count) +{ + __insw(port, buffer, count); +} + +void _insl(unsigned long port, void *buffer, unsigned long count) +{ + __insl(port, buffer, count); +} + +void _outsb(unsigned long port, const void *buffer, unsigned long count) +{ + __outsb(port, buffer, count); +} + +void _outsw(unsigned long port, const void *buffer, unsigned long count) +{ + __outsw(port, buffer, count); +} + +void _outsl(unsigned long port, const void *buffer, unsigned long count) +{ + __outsl(port, buffer, count); + +} + +unsigned long ___raw_readb(unsigned long addr) +{ + return __readb(addr); +} + +unsigned long ___raw_readw(unsigned long addr) +{ + return __readw(addr); +} + +unsigned long ___raw_readl(unsigned long addr) +{ + return __readl(addr); +} + +unsigned long _readb(unsigned long addr) +{ + unsigned long r = __readb(addr); + mb(); + return r; +} + +unsigned long _readw(unsigned long addr) +{ + unsigned long r = __readw(addr); + mb(); + return r; +} + +unsigned long _readl(unsigned long addr) +{ + unsigned long r = __readl(addr); + mb(); + return r; +} + +void ___raw_writeb(unsigned char b, unsigned long addr) +{ + __writeb(b, addr); +} + +void ___raw_writew(unsigned short b, unsigned long addr) +{ + __writew(b, addr); +} + +void ___raw_writel(unsigned int b, unsigned long addr) +{ + __writel(b, addr); +} + +void _writeb(unsigned char b, unsigned long addr) +{ + __writeb(b, addr); + mb(); +} + +void _writew(unsigned short b, unsigned long addr) +{ + __writew(b, addr); + mb(); +} + +void _writel(unsigned int b, unsigned long addr) +{ + __writel(b, addr); + mb(); +} + +/* + * Copy data from IO memory space to "real" memory space. + * This needs to be optimized. + */ +void memcpy_fromio(void * to, unsigned long from, unsigned long count) +{ + while (count) { + count--; + *(char *) to = readb(from); + ((char *) to)++; + from++; + } +} + +/* + * Copy data from "real" memory space to IO memory space. + * This needs to be optimized. + */ +void memcpy_toio(unsigned long to, const void * from, unsigned long count) +{ + while (count) { + count--; + writeb(*(char *) from, to); + ((char *) from)++; + to++; + } +} + +/* + * "memset" on IO memory space. + * This needs to be optimized. + */ +void memset_io(unsigned long dst, int c, unsigned long count) +{ + while (count) { + count--; + writeb(c, dst); + dst++; + } +} diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index 1faa01ce3..9e5793450 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c @@ -4,7 +4,8 @@ * * Copyright (C) 2000 Niibe Yutaka * - * Generic I/O routine. + * Generic I/O routine. These can be used where a machine specific version + * is not required. * * 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 @@ -14,6 +15,7 @@ #include <linux/config.h> #include <asm/io.h> +#include <asm/machvec.h> #if defined(__sh3__) /* I'm not sure SH7709 has this kind of bug */ @@ -21,19 +23,31 @@ #define DUMMY_READ_AREA6 0xba000000 #endif -#define PORT2ADDR(x) (CONFIG_IOPORT_START+(x)) +#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x)) + +unsigned long generic_io_base; static inline void delay(void) { ctrl_inw(0xa0000000); } -unsigned long inb(unsigned int port) +unsigned long generic_inb(unsigned int port) { return *(volatile unsigned char*)PORT2ADDR(port); } -unsigned long inb_p(unsigned int port) +unsigned long generic_inw(unsigned int port) +{ + return *(volatile unsigned short*)PORT2ADDR(port); +} + +unsigned long generic_inl(unsigned int port) +{ + return *(volatile unsigned long*)PORT2ADDR(port); +} + +unsigned long generic_inb_p(unsigned int port) { unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); @@ -41,23 +55,29 @@ unsigned long inb_p(unsigned int port) return v; } -unsigned long inw(unsigned int port) +unsigned long generic_inw_p(unsigned int port) { - return *(volatile unsigned short*)PORT2ADDR(port); + unsigned long v = *(volatile unsigned short*)PORT2ADDR(port); + + delay(); + return v; } -unsigned long inl(unsigned int port) +unsigned long generic_inl_p(unsigned int port) { - return *(volatile unsigned long*)PORT2ADDR(port); + unsigned long v = *(volatile unsigned long*)PORT2ADDR(port); + + delay(); + return v; } -void insb(unsigned int port, void *buffer, unsigned long count) +void generic_insb(unsigned int port, void *buffer, unsigned long count) { unsigned char *buf=buffer; while(count--) *buf++=inb(port); } -void insw(unsigned int port, void *buffer, unsigned long count) +void generic_insw(unsigned int port, void *buffer, unsigned long count) { unsigned short *buf=buffer; while(count--) *buf++=inw(port); @@ -66,7 +86,7 @@ void insw(unsigned int port, void *buffer, unsigned long count) #endif } -void insl(unsigned int port, void *buffer, unsigned long count) +void generic_insl(unsigned int port, void *buffer, unsigned long count) { unsigned long *buf=buffer; while(count--) *buf++=inl(port); @@ -75,34 +95,46 @@ void insl(unsigned int port, void *buffer, unsigned long count) #endif } -void outb(unsigned long b, unsigned int port) +void generic_outb(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; } -void outb_p(unsigned long b, unsigned int port) +void generic_outw(unsigned long b, unsigned int port) +{ + *(volatile unsigned short*)PORT2ADDR(port) = b; +} + +void generic_outl(unsigned long b, unsigned int port) +{ + *(volatile unsigned long*)PORT2ADDR(port) = b; +} + +void generic_outb_p(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; delay(); } -void outw(unsigned long b, unsigned int port) +void generic_outw_p(unsigned long b, unsigned int port) { *(volatile unsigned short*)PORT2ADDR(port) = b; + delay(); } -void outl(unsigned long b, unsigned int port) +void generic_outl_p(unsigned long b, unsigned int port) { - *(volatile unsigned long*)PORT2ADDR(port) = b; + *(volatile unsigned long*)PORT2ADDR(port) = b; + delay(); } -void outsb(unsigned int port, const void *buffer, unsigned long count) +void generic_outsb(unsigned int port, const void *buffer, unsigned long count) { const unsigned char *buf=buffer; while(count--) outb(*buf++, port); } -void outsw(unsigned int port, const void *buffer, unsigned long count) +void generic_outsw(unsigned int port, const void *buffer, unsigned long count) { const unsigned short *buf=buffer; while(count--) outw(*buf++, port); @@ -111,7 +143,7 @@ void outsw(unsigned int port, const void *buffer, unsigned long count) #endif } -void outsl(unsigned int port, const void *buffer, unsigned long count) +void generic_outsl(unsigned int port, const void *buffer, unsigned long count) { const unsigned long *buf=buffer; while(count--) outl(*buf++, port); @@ -119,3 +151,52 @@ void outsl(unsigned int port, const void *buffer, unsigned long count) ctrl_inb (DUMMY_READ_AREA6); #endif } + +unsigned long generic_readb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +unsigned long generic_readw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +unsigned long generic_readl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +void generic_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +void generic_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +void generic_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} + +void * generic_ioremap(unsigned long offset, unsigned long size) +{ + return (void *) P2SEGADDR(offset); +} + +void * generic_ioremap_nocache (unsigned long offset, unsigned long size) +{ + return (void *) P2SEGADDR(offset); +} + +void generic_iounmap(void *addr) +{ +} + +unsigned long generic_isa_port2addr(unsigned long offset) +{ + return offset + generic_io_base; +} diff --git a/arch/sh/kernel/io_hd64461.c b/arch/sh/kernel/io_hd64461.c index 7c655942b..3fbe6f2d0 100644 --- a/arch/sh/kernel/io_hd64461.c +++ b/arch/sh/kernel/io_hd64461.c @@ -10,15 +10,36 @@ static __inline__ unsigned long PORT2ADDR(unsigned long port) { + /* 16550A: HD64461 internal */ + if (0x3f8<=port && port<=0x3ff) + return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1); + if (0x2f8<=port && port<=0x2ff) + return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1); + +#ifdef CONFIG_HD64461_ENABLER + /* NE2000: HD64461 PCMCIA channel 0 (I/O) */ + if (0x300<=port && port<=0x31f) + return 0xba000000 + port; + + /* ide0: HD64461 PCMCIA channel 1 (memory) */ + /* On HP690, CF in slot 1 is configured as a memory card + device. See CF+ and CompactFlash Specification for the + detail of CF's memory mapped addressing. */ + if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port; + if (port == 0x3f6) return 0xb50001fe; +#endif + + /* ??? */ + if (port < 0x10000) return 0xa0000000 + port; + /* HD64461 internal devices (0xb0000000) */ - if (port < 0x10000) return CONFIG_HD64461_IOBASE + port; + if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000; /* PCMCIA channel 0, I/O (0xba000000) */ - if (port < 0x20000) return 0xba000000 + port - 0x10000; + if (port < 0x30000) return 0xba000000 + port - 0x20000; - /* PCMCIA channel 1, memory (0xb5000000) - SH7709 cannot support I/O card attached to Area 5 */ - if (port < 0x30000) return 0xb5000000 + port - 0x20000; + /* PCMCIA channel 1, memory (0xb5000000) */ + if (port < 0x40000) return 0xb5000000 + port - 0x30000; /* Whole physical address space (0xa0000000) */ return 0xa0000000 + (port & 0x1fffffff); @@ -29,80 +50,80 @@ static inline void delay(void) ctrl_inw(0xa0000000); } -unsigned long inb(unsigned int port) +unsigned long hd64461_inb(unsigned int port) { return *(volatile unsigned char*)PORT2ADDR(port); } -unsigned long inb_p(unsigned int port) +unsigned long hd64461_inb_p(unsigned int port) { unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); delay(); return v; } -unsigned long inw(unsigned int port) +unsigned long hd64461_inw(unsigned int port) { return *(volatile unsigned short*)PORT2ADDR(port); } -unsigned long inl(unsigned int port) +unsigned long hd64461_inl(unsigned int port) { return *(volatile unsigned long*)PORT2ADDR(port); } -void insb(unsigned int port, void *buffer, unsigned long count) +void hd64461_insb(unsigned int port, void *buffer, unsigned long count) { unsigned char *buf=buffer; while(count--) *buf++=inb(port); } -void insw(unsigned int port, void *buffer, unsigned long count) +void hd64461_insw(unsigned int port, void *buffer, unsigned long count) { unsigned short *buf=buffer; while(count--) *buf++=inw(port); } -void insl(unsigned int port, void *buffer, unsigned long count) +void hd64461_insl(unsigned int port, void *buffer, unsigned long count) { unsigned long *buf=buffer; while(count--) *buf++=inl(port); } -void outb(unsigned long b, unsigned int port) +void hd64461_outb(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; } -void outb_p(unsigned long b, unsigned int port) +void hd64461_outb_p(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; delay(); } -void outw(unsigned long b, unsigned int port) +void hd64461_outw(unsigned long b, unsigned int port) { *(volatile unsigned short*)PORT2ADDR(port) = b; } -void outl(unsigned long b, unsigned int port) +void hd64461_outl(unsigned long b, unsigned int port) { *(volatile unsigned long*)PORT2ADDR(port) = b; } -void outsb(unsigned int port, const void *buffer, unsigned long count) +void hd64461_outsb(unsigned int port, const void *buffer, unsigned long count) { const unsigned char *buf=buffer; while(count--) outb(*buf++, port); } -void outsw(unsigned int port, const void *buffer, unsigned long count) +void hd64461_outsw(unsigned int port, const void *buffer, unsigned long count) { const unsigned short *buf=buffer; while(count--) outw(*buf++, port); } -void outsl(unsigned int port, const void *buffer, unsigned long count) +void hd64461_outsl(unsigned int port, const void *buffer, unsigned long count) { const unsigned long *buf=buffer; while(count--) outl(*buf++, port); diff --git a/arch/sh/kernel/io_se.c b/arch/sh/kernel/io_se.c index a16c4738d..4d9eeca3b 100644 --- a/arch/sh/kernel/io_se.c +++ b/arch/sh/kernel/io_se.c @@ -56,7 +56,7 @@ shifted_port(unsigned int port) printk("bad PC-like io %s for port 0x%x at 0x%08x\n", \ #name, (port), (__u32) __builtin_return_address(0)) -unsigned long inb(unsigned int port) +unsigned long se_inb(unsigned int port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); @@ -66,7 +66,7 @@ unsigned long inb(unsigned int port) return (*port2adr(port))&0xff; } -unsigned long inb_p(unsigned int port) +unsigned long se_inb_p(unsigned int port) { unsigned long v; @@ -80,7 +80,7 @@ unsigned long inb_p(unsigned int port) return v; } -unsigned long inw(unsigned int port) +unsigned long se_inw(unsigned int port) { if (port >= 0x2000 || (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) @@ -90,13 +90,13 @@ unsigned long inw(unsigned int port) return 0; } -unsigned long inl(unsigned int port) +unsigned long se_inl(unsigned int port) { maybebadio(inl, port); return 0; } -void outb(unsigned long value, unsigned int port) +void se_outb(unsigned long value, unsigned int port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) *(__u8 *)(sh_pcic_io_wbase + port) = value; @@ -106,7 +106,7 @@ void outb(unsigned long value, unsigned int port) *(port2adr(port)) = value; } -void outb_p(unsigned long value, unsigned int port) +void se_outb_p(unsigned long value, unsigned int port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) *(__u8 *)(sh_pcic_io_wbase + port) = value; @@ -117,7 +117,7 @@ void outb_p(unsigned long value, unsigned int port) delay(); } -void outw(unsigned long value, unsigned int port) +void se_outw(unsigned long value, unsigned int port) { if (port >= 0x2000 || (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) @@ -126,12 +126,12 @@ void outw(unsigned long value, unsigned int port) maybebadio(outw, port); } -void outl(unsigned long value, unsigned int port) +void se_outl(unsigned long value, unsigned int port) { maybebadio(outl, port); } -void insb(unsigned int port, void *addr, unsigned long count) +void se_insb(unsigned int port, void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); @@ -148,19 +148,19 @@ void insb(unsigned int port, void *addr, unsigned long count) } } -void insw(unsigned int port, void *addr, unsigned long count) +void se_insw(unsigned int port, void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); while (count--) *((__u16 *) addr)++ = *p; } -void insl(unsigned int port, void *addr, unsigned long count) +void se_insl(unsigned int port, void *addr, unsigned long count) { maybebadio(insl, port); } -void outsb(unsigned int port, const void *addr, unsigned long count) +void se_outsb(unsigned int port, const void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); @@ -177,24 +177,54 @@ void outsb(unsigned int port, const void *addr, unsigned long count) } } -void outsw(unsigned int port, const void *addr, unsigned long count) +void se_outsw(unsigned int port, const void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); while (count--) *p = *((__u16 *) addr)++; } -void outsl(unsigned int port, const void *addr, unsigned long count) +void se_outsl(unsigned int port, const void *addr, unsigned long count) { maybebadio(outsw, port); } + +unsigned long se_readb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +unsigned long se_readw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +unsigned long se_readl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +void se_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +void se_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +void se_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} /* Map ISA bus address to the real address. Only for PCMCIA. */ /* ISA page descriptor. */ static __u32 sh_isa_memmap[256]; -int +static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset) { int idx; @@ -212,7 +242,7 @@ sh_isa_mmap(__u32 start, __u32 length, __u32 offset) } unsigned long -sh_isa_slot(unsigned long offset) +se_isa_port2addr(unsigned long offset) { int idx; diff --git a/arch/sh/kernel/io_unknown.c b/arch/sh/kernel/io_unknown.c new file mode 100644 index 000000000..a0407cade --- /dev/null +++ b/arch/sh/kernel/io_unknown.c @@ -0,0 +1,47 @@ +/* + * linux/arch/sh/kernel/io_unknown.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * I/O routine for unknown hardware. + */ + +static unsigned int unknown_handler(void) +{ + return 0; +} + +#define UNKNOWN_ALIAS(fn) \ + void unknown_##fn(void) __attribute__ ((alias ("unknown_handler"))); + +UNKNOWN_ALIAS(inb) +UNKNOWN_ALIAS(inw) +UNKNOWN_ALIAS(inl) +UNKNOWN_ALIAS(outb) +UNKNOWN_ALIAS(outw) +UNKNOWN_ALIAS(outl) +UNKNOWN_ALIAS(inb_p) +UNKNOWN_ALIAS(inw_p) +UNKNOWN_ALIAS(inl_p) +UNKNOWN_ALIAS(outb_p) +UNKNOWN_ALIAS(outw_p) +UNKNOWN_ALIAS(outl_p) +UNKNOWN_ALIAS(insb) +UNKNOWN_ALIAS(insw) +UNKNOWN_ALIAS(insl) +UNKNOWN_ALIAS(outsb) +UNKNOWN_ALIAS(outsw) +UNKNOWN_ALIAS(outsl) +UNKNOWN_ALIAS(readb) +UNKNOWN_ALIAS(readw) +UNKNOWN_ALIAS(readl) +UNKNOWN_ALIAS(writeb) +UNKNOWN_ALIAS(writew) +UNKNOWN_ALIAS(writel) +UNKNOWN_ALIAS(isa_port2addr) +UNKNOWN_ALIAS(ioremap) +UNKNOWN_ALIAS(ioremap_nocache) +UNKNOWN_ALIAS(iounmap) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index a353b0995..6451c4c9e 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -37,10 +37,6 @@ #include <asm/irq.h> #include <linux/irq.h> -#ifdef CONFIG_HD64461 -#include <asm/hd64461.h> -#endif - /* * Micro-access to controllers is serialized over the whole * system. We never hold this lock when we call the actual @@ -94,6 +90,7 @@ struct hw_interrupt_type no_irq_type = { * Generic, controller-independent functions: */ +#if defined(CONFIG_PROC_FS) int get_irq_list(char *buf) { int i, j; @@ -105,7 +102,7 @@ int get_irq_list(char *buf) p += sprintf(p, "CPU%d ",j); *p++ = '\n'; - for (i = 0 ; i < NR_IRQS ; i++) { + for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) { action = irq_desc[i].action; if (!action) continue; @@ -120,6 +117,7 @@ int get_irq_list(char *buf) } return p - buf; } +#endif /* * This should really return information about whether @@ -243,18 +241,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, "shlr %0\n\t" "add #-16, %0\n\t" :"=z" (irq)); -#if defined(CONFIG_HD64461) - if (irq == CONFIG_HD64461_IRQ) { - unsigned short bit; - unsigned short nirr = inw(HD64461_NIRR); - unsigned short nimr = inw(HD64461_NIMR); - nirr &= ~nimr; - for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++) - if (nirr & bit) break; - if (irq == 16) irq = CONFIG_HD64461_IRQ; - else irq += HD64461_IRQBASE; - } -#endif + irq = irq_demux(irq); kstat.irqs[cpu][irq]++; desc = irq_desc + irq; @@ -330,7 +317,7 @@ int request_irq(unsigned int irq, int retval; struct irqaction * action; - if (irq >= NR_IRQS) + if (irq >= ACTUAL_NR_IRQS) return -EINVAL; if (!handler) return -EINVAL; @@ -358,7 +345,7 @@ void free_irq(unsigned int irq, void *dev_id) struct irqaction **p; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= ACTUAL_NR_IRQS) return; spin_lock_irqsave(&irq_controller_lock,flags); @@ -408,7 +395,7 @@ unsigned long probe_irq_on(void) for (i = NR_IRQS-1; i > 0; i--) { if (!irq_desc[i].action) { irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING; - if(irq_desc[i].handler->startup(i)) + if (irq_desc[i].handler->startup(i)) irq_desc[i].status |= IRQ_PENDING; } } @@ -430,7 +417,7 @@ unsigned long probe_irq_on(void) if (!(status & IRQ_AUTODETECT)) continue; - + /* It triggered already - consider it spurious. */ if (!(status & IRQ_WAITING)) { irq_desc[i].status = status & ~IRQ_AUTODETECT; diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c index 7237ba3b5..8ac95823b 100644 --- a/arch/sh/kernel/irq_imask.c +++ b/arch/sh/kernel/irq_imask.c @@ -8,6 +8,9 @@ * */ +/* NOTE: Will not work on level 15 */ + + #include <linux/ptrace.h> #include <linux/errno.h> #include <linux/kernel_stat.h> @@ -71,7 +74,7 @@ void static inline set_interrupt_registers(int ip) : "r" (~0xf0), "r" (ip << 4)); } -void disable_imask_irq(unsigned int irq) +static void disable_imask_irq(unsigned int irq) { clear_bit(irq, &imask_mask); if (interrupt_priority < IMASK_PRIORITY - irq) diff --git a/arch/sh/kernel/irq_ipr.c b/arch/sh/kernel/irq_ipr.c index 8b6b0f5ee..f229e8a12 100644 --- a/arch/sh/kernel/irq_ipr.c +++ b/arch/sh/kernel/irq_ipr.c @@ -21,6 +21,7 @@ #include <asm/system.h> #include <asm/io.h> +#include <asm/machvec.h> struct ipr_data { unsigned int addr; /* Address of Interrupt Priority Register */ @@ -29,15 +30,8 @@ struct ipr_data { }; static struct ipr_data ipr_data[NR_IRQS]; -void set_ipr_data(unsigned int irq, unsigned int addr, int pos, int priority) -{ - ipr_data[irq].addr = addr; - ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ - ipr_data[irq].priority = priority; -} - static void enable_ipr_irq(unsigned int irq); -void disable_ipr_irq(unsigned int irq); +static void disable_ipr_irq(unsigned int irq); /* shutdown is same as "disable" */ #define shutdown_ipr_irq disable_ipr_irq @@ -61,7 +55,7 @@ static struct hw_interrupt_type ipr_irq_type = { end_ipr_irq }; -void disable_ipr_irq(unsigned int irq) +static void disable_ipr_irq(unsigned int irq) { unsigned long val, flags; unsigned int addr = ipr_data[irq].addr; @@ -90,18 +84,11 @@ static void enable_ipr_irq(unsigned int irq) restore_flags(flags); } -void make_ipr_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &ipr_irq_type; - disable_ipr_irq(irq); -} - static void mask_and_ack_ipr(unsigned int irq) { disable_ipr_irq(irq); -#ifdef CONFIG_CPU_SUBTYPE_SH7709 +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { @@ -118,18 +105,39 @@ static void end_ipr_irq(unsigned int irq) enable_ipr_irq(irq); } +void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) +{ + disable_irq_nosync(irq); + ipr_data[irq].addr = addr; + ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ + ipr_data[irq].priority = priority; + + irq_desc[irq].handler = &ipr_irq_type; + disable_ipr_irq(irq); +} + void __init init_IRQ(void) { - int i; + make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); + make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); - for (i = TIMER_IRQ; i < NR_IRQS; i++) { - irq_desc[i].handler = &ipr_irq_type; - } + make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + +#ifdef SCIF_ERI_IRQ + make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); +#endif - set_ipr_data(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); - set_ipr_data(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); +#ifdef IRDA_ERI_IRQ + make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); +#endif -#ifdef CONFIG_CPU_SUBTYPE_SH7709 +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) /* * Initialize the Interrupt Controller (INTC) * registers to their power on values @@ -161,11 +169,16 @@ void __init init_IRQ(void) * You should set corresponding bits of PFC to "00" * to enable these interrupts. */ - set_ipr_data(IRQ0_IRQ, IRQ0_IRP_ADDR, IRQ0_IRP_POS, IRQ0_PRIORITY); - set_ipr_data(IRQ1_IRQ, IRQ1_IRP_ADDR, IRQ1_IRP_POS, IRQ1_PRIORITY); - set_ipr_data(IRQ2_IRQ, IRQ2_IRP_ADDR, IRQ2_IRP_POS, IRQ2_PRIORITY); - set_ipr_data(IRQ3_IRQ, IRQ3_IRP_ADDR, IRQ3_IRP_POS, IRQ3_PRIORITY); - set_ipr_data(IRQ4_IRQ, IRQ4_IRP_ADDR, IRQ4_IRP_POS, IRQ4_PRIORITY); - set_ipr_data(IRQ5_IRQ, IRQ5_IRP_ADDR, IRQ5_IRP_POS, IRQ5_PRIORITY); -#endif /* CONFIG_CPU_SUBTYPE_SH7709 */ + make_ipr_irq(IRQ0_IRQ, IRQ0_IRP_ADDR, IRQ0_IRP_POS, IRQ0_PRIORITY); + make_ipr_irq(IRQ1_IRQ, IRQ1_IRP_ADDR, IRQ1_IRP_POS, IRQ1_PRIORITY); + make_ipr_irq(IRQ2_IRQ, IRQ2_IRP_ADDR, IRQ2_IRP_POS, IRQ2_PRIORITY); + make_ipr_irq(IRQ3_IRQ, IRQ3_IRP_ADDR, IRQ3_IRP_POS, IRQ3_PRIORITY); + make_ipr_irq(IRQ4_IRQ, IRQ4_IRP_ADDR, IRQ4_IRP_POS, IRQ4_PRIORITY); + make_ipr_irq(IRQ5_IRQ, IRQ5_IRP_ADDR, IRQ5_IRP_POS, IRQ5_PRIORITY); +#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ + + /* Perform the machine specific initialisation */ + if (sh_mv.mv_init_irq != NULL) { + sh_mv.mv_init_irq(); + } } diff --git a/arch/sh/kernel/led_se.c b/arch/sh/kernel/led_se.c new file mode 100644 index 000000000..0476f1bd8 --- /dev/null +++ b/arch/sh/kernel/led_se.c @@ -0,0 +1,67 @@ +/* + * linux/arch/sh/kernel/led_se.c + * + * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Solution Engine specific LED code. + */ + +#include <linux/config.h> + +static void mach_led(int position, int value) +{ + volatile unsigned short* p = (volatile unsigned short*)0xb0c00000; + + if (value) { + *p |= (1<<8); + } else { + *p &= ~(1<<8); + } +} + +#ifdef CONFIG_HEARTBEAT + +#include <linux/sched.h> + +/* Cycle the LED's in the clasic Knightrider/Sun pattern */ +void heartbeat_se(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short* p = (volatile unsigned short*)0xb0c00000; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) { + return; + } + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ( (300<<FSHIFT)/ + ((avenrun[0]/5) + (3<<FSHIFT)) ); + + if (up) { + if (bit == 7) { + bit--; + up=0; + } else { + bit ++; + } + } else { + if (bit == 0) { + bit++; + up=1; + } else { + bit--; + } + } + *p = 1<<(bit+8); + +} +#endif /* CONFIG_HEARTBEAT */ diff --git a/arch/sh/kernel/mach_hp600.c b/arch/sh/kernel/mach_hp600.c new file mode 100644 index 000000000..6f68d1af7 --- /dev/null +++ b/arch/sh/kernel/mach_hp600.c @@ -0,0 +1,63 @@ +/* + * linux/arch/sh/kernel/mach_hp600.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the HP600 + */ + +#include <linux/init.h> + +#include <asm/machvec.h> +#include <asm/machvec_init.h> + +#include <asm/io_hd64461.h> +#include <asm/io_generic.h> +#include <asm/irq.h> + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_hp600 __initmv = { + mv_name: "HP600", + + mv_nr_irqs: 80, /* HD64461_IRQBASE+16, see hd64461.h */ + + mv_inb: hd64461_inb, + mv_inw: hd64461_inw, + mv_inl: hd64461_inl, + mv_outb: hd64461_outb, + mv_outw: hd64461_outw, + mv_outl: hd64461_outl, + + mv_inb_p: hd64461_inb_p, + mv_inw_p: hd64461_inw, + mv_inl_p: hd64461_inl, + mv_outb_p: hd64461_outb_p, + mv_outw_p: hd64461_outw, + mv_outl_p: hd64461_outl, + + mv_insb: hd64461_insb, + mv_insw: hd64461_insw, + mv_insl: hd64461_insl, + mv_outsb: hd64461_outsb, + mv_outsw: hd64461_outsw, + mv_outsl: hd64461_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_irq_demux: hd64461_irq_demux, + + mv_hw_hp600: 1, + mv_hw_hd64461: 1, +}; +ALIAS_MV(hp600) diff --git a/arch/sh/kernel/mach_se.c b/arch/sh/kernel/mach_se.c new file mode 100644 index 000000000..ce142a399 --- /dev/null +++ b/arch/sh/kernel/mach_se.c @@ -0,0 +1,80 @@ +/* + * linux/arch/sh/kernel/mach_se.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Hitachi SolutionEngine + */ + +#include <linux/init.h> + +#include <asm/machvec.h> +#include <asm/machvec_init.h> + +#include <asm/io_se.h> + +void heartbeat_se(void); +void setup_se(void); +void init_se_IRQ(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_se __initmv = { + mv_name: "SolutionEngine", + +#if defined(__SH4__) + mv_nr_irqs: 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + mv_nr_irqs: 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + mv_nr_irqs: 61, +#endif + + mv_inb: se_inb, + mv_inw: se_inw, + mv_inl: se_inl, + mv_outb: se_outb, + mv_outw: se_outw, + mv_outl: se_outl, + + mv_inb_p: se_inb_p, + mv_inw_p: se_inw, + mv_inl_p: se_inl, + mv_outb_p: se_outb_p, + mv_outw_p: se_outw, + mv_outl_p: se_outl, + + mv_insb: se_insb, + mv_insw: se_insw, + mv_insl: se_insl, + mv_outsb: se_outsb, + mv_outsw: se_outsw, + mv_outsl: se_outsl, + + mv_readb: se_readb, + mv_readw: se_readw, + mv_readl: se_readl, + mv_writeb: se_writeb, + mv_writew: se_writew, + mv_writel: se_writel, + + mv_ioremap: generic_ioremap, + mv_ioremap_nocache: generic_ioremap_nocache, + mv_iounmap: generic_iounmap, + + mv_isa_port2addr: se_isa_port2addr, + + mv_init_arch: setup_se, + mv_init_irq: init_se_IRQ, +#ifdef CONFIG_HEARTBEAT + mv_heartbeat: heartbeat_se, +#endif + + mv_hw_se: 1, +}; +ALIAS_MV(se) diff --git a/arch/sh/kernel/mach_unknown.c b/arch/sh/kernel/mach_unknown.c new file mode 100644 index 000000000..895a65c1d --- /dev/null +++ b/arch/sh/kernel/mach_unknown.c @@ -0,0 +1,68 @@ +/* + * linux/arch/sh/kernel/mach_unknown.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine specific code for an unknown machine (internal peripherials only) + */ + +#include <linux/init.h> + +#include <asm/machvec.h> +#include <asm/machvec_init.h> + +#include <asm/io_unknown.h> + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_unknown __initmv = { + mv_name: "Unknown", + +#if defined(__SH4__) + mv_nr_irqs: 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + mv_nr_irqs: 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + mv_nr_irqs: 61, +#endif + + mv_inb: unknown_inb, + mv_inw: unknown_inw, + mv_inl: unknown_inl, + mv_outb: unknown_outb, + mv_outw: unknown_outw, + mv_outl: unknown_outl, + + mv_inb_p: unknown_inb_p, + mv_inw_p: unknown_inw_p, + mv_inl_p: unknown_inl_p, + mv_outb_p: unknown_outb_p, + mv_outw_p: unknown_outw_p, + mv_outl_p: unknown_outl_p, + + mv_insb: unknown_insb, + mv_insw: unknown_insw, + mv_insl: unknown_insl, + mv_outsb: unknown_outsb, + mv_outsw: unknown_outsw, + mv_outsl: unknown_outsl, + + mv_readb: unknown_readb, + mv_readw: unknown_readw, + mv_readl: unknown_readl, + mv_writeb: unknown_writeb, + mv_writew: unknown_writew, + mv_writel: unknown_writel, + + mv_ioremap: unknown_ioremap, + mv_ioremap_nocache: unknown_ioremap_nocache, + mv_iounmap: unknown_iounmap, + + mv_isa_port2addr: unknown_isa_port2addr, +}; +ALIAS_MV(unknown) diff --git a/arch/sh/kernel/pci-sh.c b/arch/sh/kernel/pci-sh.c index 3613596f7..a4a6c6918 100644 --- a/arch/sh/kernel/pci-sh.c +++ b/arch/sh/kernel/pci-sh.c @@ -4,9 +4,22 @@ #include <linux/init.h> #include <linux/ioport.h> #include <linux/errno.h> +#include <asm/machvec.h> -unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, - unsigned long start, unsigned long size) +void __init pcibios_init(void) { - return start; + if (sh_mv.mv_init_pci != NULL) { + sh_mv.mv_init_pci(); + } } + +/* Haven't done anything here as yet */ +char * __init pcibios_setup(char *str) +{ + return str; +} + +/* We don't have anything here to fixup */ +struct pci_fixup pcibios_fixups[] = { + {0, 0, 0, NULL} +}; diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c index c958745b5..f733501c1 100644 --- a/arch/sh/kernel/semaphore.c +++ b/arch/sh/kernel/semaphore.c @@ -12,6 +12,8 @@ #include <asm/semaphore.h> #include <asm/semaphore-helper.h> +spinlock_t semaphore_wake_lock; + /* * Semaphores are implemented using a two-way counter: * The "count" variable is decremented for each process diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index be56f8570..aaea2e6df 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -30,13 +30,16 @@ #endif #include <linux/bootmem.h> #include <linux/console.h> +#include <linux/ctype.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/system.h> #include <asm/io.h> +#include <asm/io_generic.h> #include <asm/smp.h> +#include <asm/machvec.h> #ifdef CONFIG_SH_EARLY_PRINTK #include <asm/sh_bios.h> #endif @@ -53,10 +56,18 @@ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ extern int rd_image_start; /* starting block # of image */ #endif +#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN) +struct sh_machine_vector sh_mv; +#endif + extern void fpu_init(void); extern int root_mountflags; extern int _text, _etext, _edata, _end; +#define MV_NAME_SIZE 32 + +static struct sh_machine_vector* __init get_mv_byname(const char* name); + /* * This is set up by the setup-routine at boot-time */ @@ -180,8 +191,10 @@ void sh_console_unregister(void) #endif - -static inline void parse_mem_cmdline (char ** cmdline_p) +static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], + struct sh_machine_vector** mvp, + unsigned long *mv_io_base, + int *mv_mmio_enable) { char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; @@ -208,6 +221,35 @@ static inline void parse_mem_cmdline (char ** cmdline_p) memory_end = memory_start + mem_size; } } + if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { + char* mv_end; + char* mv_comma; + int mv_len; + if (to != command_line) + to--; + from += 6; + mv_end = strchr(from, ' '); + if (mv_end == NULL) + mv_end = from + strlen(from); + + mv_comma = strchr(from, ','); + if ((mv_comma != NULL) && (mv_comma < mv_end)) { + int ints[3]; + get_options(mv_comma+1, ARRAY_SIZE(ints), ints); + *mv_io_base = ints[1]; + *mv_mmio_enable = ints[2]; + mv_len = mv_comma - from; + } else { + mv_len = mv_end - from; + } + if (mv_len > (MV_NAME_SIZE-1)) + mv_len = MV_NAME_SIZE-1; + memcpy(mv_name, from, mv_len); + mv_name[mv_len] = '\0'; + from = mv_end; + + *mvp = get_mv_byname(mv_name); + } c = *(from++); if (!c) break; @@ -221,6 +263,10 @@ static inline void parse_mem_cmdline (char ** cmdline_p) void __init setup_arch(char **cmdline_p) { + struct sh_machine_vector *mv = NULL; + char mv_name[MV_NAME_SIZE] = ""; + unsigned long mv_io_base = 0; + int mv_mmio_enable = 0; unsigned long bootmap_size; unsigned long start_pfn, max_pfn, max_low_pfn; @@ -248,7 +294,58 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_bus(&_etext); data_resource.end = virt_to_bus(&_edata)-1; - parse_mem_cmdline(cmdline_p); + parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); + +#ifdef CONFIG_SH_GENERIC + if (mv == NULL) { + extern struct sh_machine_vector mv_unknown; + mv = &mv_unknown; + if (*mv_name != '\0') { + printk("Warning: Unsupported machine %s, using unknown\n", + mv_name); + } + } + sh_mv = *mv; +#endif +#ifdef CONFIG_SH_UNKNOWN + sh_mv = mv_unknown; +#endif + +#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN) + if (mv_io_base != 0) { + sh_mv.mv_inb = generic_inb; + sh_mv.mv_inw = generic_inw; + sh_mv.mv_inl = generic_inl; + sh_mv.mv_outb = generic_outb; + sh_mv.mv_outw = generic_outw; + sh_mv.mv_outl = generic_outl; + + sh_mv.mv_inb_p = generic_inb_p; + sh_mv.mv_inw_p = generic_inw_p; + sh_mv.mv_inl_p = generic_inl_p; + sh_mv.mv_outb_p = generic_outb_p; + sh_mv.mv_outw_p = generic_outw_p; + sh_mv.mv_outl_p = generic_outl_p; + + sh_mv.mv_insb = generic_insb; + sh_mv.mv_insw = generic_insw; + sh_mv.mv_insl = generic_insl; + sh_mv.mv_outsb = generic_outsb; + sh_mv.mv_outsw = generic_outsw; + sh_mv.mv_outsl = generic_outsl; + + sh_mv.mv_isa_port2addr = generic_isa_port2addr; + generic_io_base = mv_io_base; + } + if (mv_mmio_enable != 0) { + sh_mv.mv_readb = generic_readb; + sh_mv.mv_readw = generic_readw; + sh_mv.mv_readl = generic_readl; + sh_mv.mv_writeb = generic_writeb; + sh_mv.mv_writew = generic_writew; + sh_mv.mv_writel = generic_writel; + } +#endif #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) @@ -358,6 +455,11 @@ void __init setup_arch(char **cmdline_p) #endif #endif + /* Perform the machine specific initialisation */ + if (sh_mv.mv_init_arch != NULL) { + sh_mv.mv_init_arch(); + } + #if defined(__SH4__) /* We already grab/initialized FPU in head.S. Make it consisitent. */ init_task.used_math = 1; @@ -366,10 +468,32 @@ void __init setup_arch(char **cmdline_p) paging_init(); } +struct sh_machine_vector* __init get_mv_byname(const char* name) +{ + extern int strcasecmp(const char *, const char *); + extern long __machvec_start, __machvec_end; + struct sh_machine_vector *all_vecs = + (struct sh_machine_vector *)&__machvec_start; + + int i, n = ((unsigned long)&__machvec_end + - (unsigned long)&__machvec_start)/ + sizeof(struct sh_machine_vector); + + for (i = 0; i < n; ++i) { + struct sh_machine_vector *mv = &all_vecs[i]; + if (mv == NULL) + continue; + if (strcasecmp(name, mv->mv_name) == 0) { + return mv; + } + } + return NULL; +} + /* * Get CPU information for use by the procfs. */ - +#ifdef CONFIG_PROC_FS int get_cpuinfo(char *buffer) { char *p = buffer; @@ -384,6 +508,7 @@ int get_cpuinfo(char *buffer) p += sprintf(p, "bogomips\t: %lu.%02lu\n\n", (loops_per_sec+2500)/500000, ((loops_per_sec+2500)/5000) % 100); + p += sprintf(p, "Machine: %s\n", sh_mv.mv_name); #define PRINT_CLOCK(name, value) \ p += sprintf(p, name " clock: %d.%02dMHz\n", \ @@ -395,3 +520,4 @@ int get_cpuinfo(char *buffer) return p - buffer; } +#endif diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c new file mode 100644 index 000000000..3e0422154 --- /dev/null +++ b/arch/sh/kernel/setup_cqreek.c @@ -0,0 +1,224 @@ +/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $ + * + * arch/sh/kernel/setup_cqreek.c + * + * Copyright (C) 2000 Niibe Yutaka + * + * CqREEK IDE/ISA Bridge Support. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/io_generic.h> +#include <asm/irq.h> +#include <asm/machvec.h> +#include <asm/machvec_init.h> + +#define BRIDGE_FEATURE 0x0002 + +#define BRIDGE_IDE_CTRL 0x0018 +#define BRIDGE_IDE_INTR_LVL 0x001A +#define BRIDGE_IDE_INTR_MASK 0x001C +#define BRIDGE_IDE_INTR_STAT 0x001E + +#define BRIDGE_ISA_CTRL 0x0028 +#define BRIDGE_ISA_INTR_LVL 0x002A +#define BRIDGE_ISA_INTR_MASK 0x002C +#define BRIDGE_ISA_INTR_STAT 0x002E + +#define IDE_OFFSET 0xA4000000UL +#define ISA_OFFSET 0xA4A00000UL + +static unsigned long cqreek_port2addr(unsigned long port) +{ + if (0x0000<=port && port<=0x0040) + return IDE_OFFSET + port; + if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6) + return IDE_OFFSET + port; + + return ISA_OFFSET + port; +} + +static void disable_cqreek_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short mask; + + save_and_cli(flags); + /* Disable IRQ */ + mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq); + outw_p(mask, BRIDGE_ISA_INTR_MASK); + restore_flags(flags); +} + +static void enable_cqreek_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short mask; + + save_and_cli(flags); + /* Enable IRQ */ + mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq); + outw_p(mask, BRIDGE_ISA_INTR_MASK); + restore_flags(flags); +} + +#define CLEAR_AT_ACCEPT + +static void mask_and_ack_cqreek(unsigned int irq) +{ + inw(BRIDGE_ISA_INTR_STAT); + disable_cqreek_irq(irq); +#ifdef CLEAR_AT_ACCEPT + /* Clear IRQ (it might be edge IRQ) */ + outw_p((1<<irq), BRIDGE_ISA_INTR_STAT); +#endif +} + +static void end_cqreek_irq(unsigned int irq) +{ +#ifndef CLEAR_AT_ACCEPT + /* Clear IRQ (it might be edge IRQ) */ + outw_p((1<<irq), BRIDGE_ISA_INTR_STAT); +#endif + enable_cqreek_irq(irq); +} + +static unsigned int startup_cqreek_irq(unsigned int irq) +{ + enable_cqreek_irq(irq); + return 0; +} + +static void shutdown_cqreek_irq(unsigned int irq) +{ + disable_cqreek_irq(irq); +} + +static struct hw_interrupt_type cqreek_irq_type = { + "CQREEK-IRQ", + startup_cqreek_irq, + shutdown_cqreek_irq, + enable_cqreek_irq, + disable_cqreek_irq, + mask_and_ack_cqreek, + end_cqreek_irq +}; + +static int has_ide, has_isa; + +/* XXX: This is just for test for my NE2000 ISA board + What we really need is virtualized IRQ and demultiplexer like HP600 port */ +void __init init_cqreek_IRQ(void) +{ + if (has_ide) + make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14); + + if (has_isa) { + /* XXX: Err... we may need demultiplexer for ISA irq... */ + irq_desc[10].handler = &cqreek_irq_type; + irq_desc[10].status = IRQ_DISABLED; + irq_desc[10].action = 0; + irq_desc[10].depth = 1; + + disable_cqreek_irq(10); + } +} + +/* + * Initialize the board + */ +void __init setup_cqreek(void) +{ + int i; +/* udelay is not available at setup time yet... */ +#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0) + + if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */ + outw_p(0, BRIDGE_IDE_INTR_LVL); + outw_p(0, BRIDGE_IDE_INTR_MASK); + + outw_p(0, BRIDGE_IDE_CTRL); + DELAY(); + + outw_p(0x8000, BRIDGE_IDE_CTRL); + DELAY(); + + outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */ + outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */ + outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */ + has_ide=1; + } + + if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */ + outw_p(0, BRIDGE_ISA_INTR_LVL); + outw_p(0, BRIDGE_ISA_INTR_MASK); + + outw_p(0, BRIDGE_ISA_CTRL); + DELAY(); + outw_p(0x8000, BRIDGE_ISA_CTRL); + DELAY(); + + outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */ + outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */ + outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */ + has_isa=1; + } + + printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", has_ide, has_isa); +} + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_cqreek __initmv = { + mv_name: "CqREEK", + +#if defined(__SH4__) + mv_nr_irqs: 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + mv_nr_irqs: 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + mv_nr_irqs: 61, +#endif + + mv_inb: generic_inb, + mv_inw: generic_inw, + mv_inl: generic_inl, + mv_outb: generic_outb, + mv_outw: generic_outw, + mv_outl: generic_outl, + + mv_inb_p: generic_inb_p, + mv_inw_p: generic_inw_p, + mv_inl_p: generic_inl_p, + mv_outb_p: generic_outb_p, + mv_outw_p: generic_outw_p, + mv_outl_p: generic_outl_p, + + mv_insb: generic_insb, + mv_insw: generic_insw, + mv_insl: generic_insl, + mv_outsb: generic_outsb, + mv_outsw: generic_outsw, + mv_outsl: generic_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_init_arch: setup_cqreek, + mv_init_irq: init_cqreek_IRQ, + + mv_port2addr: cqreek_port2addr, + mv_isa_port2addr: cqreek_port2addr, +}; +ALIAS_MV(cqreek) diff --git a/arch/sh/kernel/setup_hd64461.c b/arch/sh/kernel/setup_hd64461.c index 0ee07e887..6132e420d 100644 --- a/arch/sh/kernel/setup_hd64461.c +++ b/arch/sh/kernel/setup_hd64461.c @@ -92,6 +92,20 @@ static void hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs) inw(HD64461_NIRR), inw(HD64461_NIMR)); } +int hd64461_irq_demux(int irq) +{ + if (irq == CONFIG_HD64461_IRQ) { + unsigned short bit; + unsigned short nirr = inw(HD64461_NIRR); + unsigned short nimr = inw(HD64461_NIMR); + nirr &= ~nimr; + for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++) + if (nirr & bit) break; + if (irq == 16) irq = CONFIG_HD64461_IRQ; + else irq += HD64461_IRQBASE; + } + return irq; +} static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL}; @@ -100,10 +114,13 @@ int __init setup_hd64461(void) { int i; + if (!MACH_HD64461) + return 0; + printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE, HD64461_IRQBASE+15); -#if 1 +#ifdef CONFIG_CPU_SUBTYPE_SH7709 /* IRQ line for HD64461 should be set level trigger mode("10"). */ /* And this should be done earlier than the kernel starts. */ ctrl_outw(0x0200, INTC_ICR1); /* when connected to IRQ4. */ diff --git a/arch/sh/kernel/setup_se.c b/arch/sh/kernel/setup_se.c index cd9436fff..8b2f59972 100644 --- a/arch/sh/kernel/setup_se.c +++ b/arch/sh/kernel/setup_se.c @@ -73,10 +73,8 @@ static void __init init_smsc(void) /* * Initialize IRQ setting */ -static void __init init_se_IRQ(void) +void __init init_se_IRQ(void) { - int i; - /* * Super I/O (Just mimic PC): * 1: keyboard @@ -88,43 +86,34 @@ static void __init init_se_IRQ(void) * 12: mouse * 14: ide0 */ - set_ipr_data(14, BCR_ILCRA, 2, 0x0f-14); - set_ipr_data(12, BCR_ILCRA, 1, 0x0f-12); - set_ipr_data( 8, BCR_ILCRB, 1, 0x0f- 8); - set_ipr_data( 6, BCR_ILCRC, 3, 0x0f- 6); - set_ipr_data( 5, BCR_ILCRC, 2, 0x0f- 5); - set_ipr_data( 4, BCR_ILCRC, 1, 0x0f- 4); - set_ipr_data( 3, BCR_ILCRC, 0, 0x0f- 3); - set_ipr_data( 1, BCR_ILCRD, 3, 0x0f- 1); - - set_ipr_data(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ - - set_ipr_data( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ - set_ipr_data(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ - set_ipr_data( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ - set_ipr_data( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ + make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); + make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); + make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); + make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); + make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); + make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); + make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); + make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); + + make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ + + make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ + make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ + make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ + make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ /* NOTE: #2 and #13 are not used on PC */ - set_ipr_data(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ - set_ipr_data( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ - - for (i = 0; i < 15; i++) { - make_ipr_irq(i); - } + make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ + make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ } + /* * Initialize the board */ -int __init setup_se(void) +void __init setup_se(void) { - init_se_IRQ(); init_smsc(); /* XXX: RTC setting comes here */ - - printk(KERN_INFO "Hitach SolutionEngine Setup...done\n"); - return 0; } - -module_init(setup_se); diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index a24b4a842..12f716249 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id: sh_bios.c,v 1.2 2000/07/26 04:37:32 gniibe Exp $ * * linux/arch/sh/kernel/sh_bios.c * C interface for trapping into the standard LinuxSH BIOS. diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 221af3022..9bdddc9d9 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -198,13 +198,16 @@ static inline int save_sigcontext_fpu(struct sigcontext *sc) { struct task_struct *tsk = current; unsigned long flags; + int val; if (!tsk->used_math) { - __copy_to_user(&sc->sc_ownedfp, 0, sizeof(int)); + val = 0; + __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); return 0; } - __copy_to_user(&sc->sc_ownedfp, 1, sizeof(int)); + val = 1; + __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); /* This will cause a "finit" to be triggered by the next attempted FPU operation by the 'current' process. diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 2c73255f4..f1e8d28bf 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -26,6 +26,7 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/delay.h> +#include <asm/machvec.h> #include <linux/timex.h> #include <linux/irq.h> @@ -226,6 +227,11 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg sh_do_profile(regs->pc); #endif +#ifdef CONFIG_HEARTBEAT + if (sh_mv.mv_heartbeat != NULL) + sh_mv.mv_heartbeat(); +#endif + /* * If we have an externally synchronized Linux clock, then update * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be @@ -441,11 +447,11 @@ void __init time_init(void) tmp = (frqcr & 0x2000) >> 11; tmp |= frqcr & 0x0003; pfc = pfc_table[tmp]; -#ifdef CONFIG_SH_HP600 - master_clock = cpu_clock/6; -#else - master_clock = cpu_clock; -#endif + if (MACH_HP600) { + master_clock = cpu_clock/6; + } else { + master_clock = cpu_clock; + } bus_clock = master_clock/pfc; } #elif defined(__SH4__) diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 7af24f1c3..a0d344cb9 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -7,6 +7,6 @@ L_TARGET = lib.a L_OBJS = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ - checksum.o + checksum.o strcasecmp.o include $(TOPDIR)/Rules.make diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S index b34a65383..3317b3ccc 100644 --- a/arch/sh/lib/checksum.S +++ b/arch/sh/lib/checksum.S @@ -185,15 +185,65 @@ ENTRY(csum_partial_copy_generic) mov.l r5,@-r15 mov.l r6,@-r15 + mov #3, r0 ! Check src and dest are equally aligned + mov r4, r1 + and r0, r1 + and r5, r0 + cmp/eq r1, r0 + bf 3f ! Different alignments, use slow version + tst #1,r0 ! Check dest word aligned + bf 3f ! If not, do it the slow way + mov #2,r0 - tst r0,r5 ! Check alignment. + tst r0,r5 ! Check dest alignment. bt 2f ! Jump if alignment is ok. add #-2,r6 ! Alignment uses up two bytes. cmp/pz r6 ! Jump if we had at least two bytes. bt/s 1f clrt bra 4f - add #2,r6 ! $r6 was < 2. Deal with it. + add #2,r6 ! $r6 was < 2. Deal with it. + +3: ! Handle different src and dest alinments. + ! This is not common, so simple byte by byte copy will do. + mov r6, r2 + shlr r6 + tst r6, r6 + bt 4f + clrt +SRC(5: mov.b @r4+,r0 ) +DST( mov.b r0,@r5 ) + add #1, r5 +SRC( mov.b @r4+,r1 ) +DST( mov.b r1,@r5 ) + add #1,r5 + + extu.b r0,r0 + extu.b r1,r1 +#ifdef __LITTLE_ENDIAN__ + shll8 r1 +#else + shll8 r0 +#endif + or r1,r0 + + addc r0,r7 + movt r0 + dt r6 + bf/s 5b + cmp/eq #1,r0 + mov #0,r0 + addc r0, r7 + + mov r2, r0 + tst #1, r0 + bt 7f + bra 5f + clrt + + ! src and dest equally aligned, but to a two byte boundary. + ! Handle first two bytes as a special case + .align 5 SRC(1: mov.w @r4+,r0 ) DST( mov.w r0,@r5 ) add #2,r5 diff --git a/arch/sh/lib/strcasecmp.c b/arch/sh/lib/strcasecmp.c new file mode 100644 index 000000000..4e57a216f --- /dev/null +++ b/arch/sh/lib/strcasecmp.c @@ -0,0 +1,26 @@ +/* + * linux/arch/alpha/lib/strcasecmp.c + */ + +#include <linux/string.h> + + +/* We handle nothing here except the C locale. Since this is used in + only one place, on strings known to contain only 7 bit ASCII, this + is ok. */ + +int strcasecmp(const char *a, const char *b) +{ + int ca, cb; + + do { + ca = *a++ & 0xff; + cb = *b++ & 0xff; + if (ca >= 'A' && ca <= 'Z') + ca += 'a' - 'A'; + if (cb >= 'A' && cb <= 'Z') + cb += 'a' - 'A'; + } while (ca == cb && ca != '\0'); + + return ca - cb; +} diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 981c25380..1f1815600 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -8,6 +8,6 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -O_OBJS := init.o fault.o ioremap.o extable.o cache.o +O_OBJS := init.o fault.o extable.o cache.o # ioremap.o include $(TOPDIR)/Rules.make diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 56f444bf4..af494b9a3 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -207,6 +207,9 @@ static void icache_purge_range(unsigned long start, unsigned long end) * compared the tag of cache and if it's not matched, nothing * will be occurred. (We can avoid flushing other caches.) * + * NOTE: We can use A-bit feature here, because we have valid + * entriy in TLB (at least in UTLB), as dcache_wback_range is + * called before this function is called. */ for (v = start; v < end; v+=L1_CACHE_BYTES) { addr = CACHE_IC_ADDRESS_ARRAY | (v&CACHE_IC_ENTRY_MASK) @@ -225,8 +228,12 @@ static void icache_purge_range(unsigned long start, unsigned long end) */ void flush_icache_range(unsigned long start, unsigned long end) { + unsigned long flags; + + save_and_cli(flags); dcache_wback_range(start, end); icache_purge_range(start, end); + restore_flags(flags); } /* @@ -238,11 +245,6 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *pg) { unsigned long phys, addr, data, i; - /* - * Alas, we don't know where the virtual address is, - * So, we can't use icache_purge_range(). - */ - /* Physical address of this page */ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; @@ -259,6 +261,30 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *pg) back_to_P1(); } +/* + * Write back & invalidate the D-cache of the page. + * (To avoid "alias" issues) + */ +void flush_dcache_page(struct page *pg) +{ + unsigned long phys, addr, data, i; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + + jump_to_P2(); + /* Loop all the D-cache */ + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~(CACHE_VALID|CACHE_UPDATED); + ctrl_outl(data, addr); + } + } + back_to_P1(); +} + void flush_cache_all(void) { unsigned long addr, data, i; @@ -298,56 +324,64 @@ void flush_cache_mm(struct mm_struct *mm) flush_cache_all(); } +/* + * Write back and invalidate D-caches. + * + * START, END: Virtual Address (U0 address) + * + * NOTE: We need to flush the _physical_ page entry. + * Flushing the cache lines for U0 only isn't enough. + * We need to flush for P1 too, which may contain aliases. + */ void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { /* - * Calling - * dcache_flush_range(start, end); - * is not good for the purpose of this function. That is, - * flushing cache lines indexed by the virtual address is not - * sufficient. - * - * Instead, we need to flush the relevant cache lines which - * hold the data of the corresponding physical memory, as we - * have "alias" issues. - * - * This is needed because, kernel accesses the memory through - * P1-area (and/or U0-area) and user-space accesses through U0-area. - * And P1-area and U0-area may use different cache lines for - * same physical memory. + * We could call flush_cache_page for the pages of these range, + * but it's not efficient (scan the caches all the time...). * - * If we would call dcache_flush_range(), the line of P1-area - * could remain in the cache, unflushed. + * We can't use A-bit magic, as there's the case we don't have + * valid entry on TLB. */ - unsigned long addr, data, v; - - start &= ~(L1_CACHE_BYTES-1); - jump_to_P2(); - - for (v = start; v < end; v+=L1_CACHE_BYTES) { - addr = CACHE_OC_ADDRESS_ARRAY | - (v&CACHE_OC_ENTRY_PHYS_MASK) | 0x8 /* A-bit */; - data = (v&0xfffffc00); /* Update=0, Valid=0 */ - - /* Try all the cases for aliases */ - ctrl_outl(data, addr); - ctrl_outl(data, addr | 0x1000); - ctrl_outl(data, addr | 0x2000); - ctrl_outl(data, addr | 0x3000); - } - back_to_P1(); + flush_cache_all(); } +/* + * Write back and invalidate D-caches for the page. + * + * ADDR: Virtual Address (U0 address) + * + * NOTE: We need to flush the _physical_ page entry. + * Flushing the cache lines for U0 only isn't enough. + * We need to flush for P1 too, which may contain aliases. + */ 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); + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + struct page *pg; + + dir = pgd_offset(vma->vm_mm, addr); + pmd = pmd_offset(dir, addr); + if (pmd_none(*pmd)) + return; + if (pmd_bad(*pmd)) + return; + pte = pte_offset(pmd, addr); + entry = *pte; + if (pte_none(entry) || !pte_present(entry)) + return; + phys = pte_val(entry)&PAGE_MASK; + pg = virt_to_page(__va(phys)); + flush_dcache_page(pg); } /* * After accessing the memory from kernel space (P1-area), we need to - * write back the cache line, to avoid "alias" issues. + * write back the cache line to maintain DMA coherency. * * We search the D-cache to see if we have the entries corresponding to * the page, and if found, write back them. diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 9dd6ae451..f2e342f0b 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -115,7 +115,8 @@ static void handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) * ITLB is not affected by "ldtlb" instruction. * So, we need to flush the entry by ourselves. */ - __flush_tlb_page(mm, address&PAGE_MASK); + if (mm) + __flush_tlb_page(mm, address&PAGE_MASK); #endif update_mmu_cache(NULL, address, entry); } @@ -281,15 +282,14 @@ void update_mmu_cache(struct vm_area_struct * vma, save_and_cli(flags); #if defined(__SH4__) - if ((vma->vm_flags & VM_SHARED)) { + if (vma && (vma->vm_flags & VM_SHARED)) { + struct page *pg; + 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); + pg = virt_to_page(__va(pteval)); + flush_dcache_page(pg); } #endif diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S index 1a7c2e820..ad1fc1c1b 100644 --- a/arch/sh/vmlinux.lds.S +++ b/arch/sh/vmlinux.lds.S @@ -61,6 +61,9 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall.init) } __initcall_end = .; + __machvec_start = .; + .machvec.init : { *(.machvec.init) } + __machvec_end = .; . = ALIGN(4096); __init_end = .; diff --git a/arch/sparc/config.in b/arch/sparc/config.in index 570f86325..e603d2a64 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.99 2000/08/01 04:53:58 anton Exp $ +# $Id: config.in,v 1.100 2000/08/07 18:06:54 anton Exp $ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # @@ -86,13 +86,23 @@ comment 'Block devices' bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD -bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD -if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then - tristate ' Linear (append) mode' CONFIG_MD_LINEAR - tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED -# tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING -# tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 -fi +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET + +#tristate 'Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM N +#if [ "$CONFIG_BLK_DEV_LVM" != "n" ]; then +# bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y +#fi + +tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD +dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD +dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD +dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD +dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD +#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then +# bool ' Boot support' CONFIG_MD_BOOT +# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID +#fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then @@ -100,9 +110,6 @@ if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then fi dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM -tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP -tristate 'Network block device support' CONFIG_BLK_DEV_NBD - endmenu if [ "$CONFIG_NET" = "y" ]; then diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index c58948e71..8bac6f8e3 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -2,6 +2,7 @@ # Automatically generated make config: don't edit # CONFIG_UID16=y +CONFIG_HIGHMEM=y # # Code maturity level options @@ -108,14 +109,16 @@ CONFIG_SUN_AURORA=m # Block devices # CONFIG_BLK_DEV_FD=y -CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m -CONFIG_MD_STRIPED=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m # # Networking options diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c index ad74d0ed2..dedb18f01 100644 --- a/arch/sparc/mm/generic.c +++ b/arch/sparc/mm/generic.c @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.9 1999/12/27 06:30:03 anton Exp $ +/* $Id: generic.c,v 1.10 2000/08/09 00:00:15 davem Exp $ * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 3d42e0c63..b0d45d82a 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.89 2000/08/01 04:53:58 anton Exp $ +/* $Id: init.c,v 1.90 2000/08/09 00:00:15 davem Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index f395f06f5..1679384d6 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -1,4 +1,4 @@ -/* $Id: io-unit.c,v 1.21 2000/02/06 22:55:45 zaitcev Exp $ +/* $Id: io-unit.c,v 1.22 2000/08/09 00:00:15 davem Exp $ * io-unit.c: IO-UNIT specific routines for memory management. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index e48128479..058fdd0d1 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -1,4 +1,4 @@ -/* $Id: iommu.c,v 1.19 2000/02/06 22:55:45 zaitcev Exp $ +/* $Id: iommu.c,v 1.20 2000/08/09 00:00:15 davem Exp $ * iommu.c: IOMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 7e76841de..96fbf1b88 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.219 2000/08/01 04:53:58 anton Exp $ +/* $Id: srmmu.c,v 1.220 2000/08/09 00:00:15 davem Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 717269b68..0ce0ca1e8 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.196 2000/07/07 07:33:11 anton Exp $ +/* $Id: sun4c.c,v 1.197 2000/08/09 00:00:15 davem Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index dab4e3bcf..c93f2efc8 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.60 2000/07/16 18:21:24 ecd Exp $ +# $Id: Makefile,v 1.61 2000/08/09 08:25:19 jj Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -64,7 +64,7 @@ binfmt_elf32.o: $(TOPDIR)/fs/binfmt_elf.c ifneq ($(NEW_GCC),y) CMODEL_CFLAG := -mmedlow else - CMODEL_CFLAG := -mcmodel=medlow + CMODEL_CFLAG := -m64 -mcmodel=medlow endif check_asm: dummy diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 3295938e6..729ecd911 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.51 2000/07/28 09:43:39 davem Exp $ +/* $Id: rtrap.S,v 1.53 2000/08/06 05:20:35 davem Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 7d8a71d6a..e77d8a385 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.158 2000/07/29 00:55:49 davem Exp $ +/* $Id: sys_sparc32.c,v 1.159 2000/08/08 02:47:50 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -1037,7 +1037,8 @@ asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times) struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; -typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *); +typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *); +typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); static long do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, u32 count) @@ -1047,14 +1048,15 @@ static long do_readv_writev32(int type, struct file *file, struct iovec *iov=iovstack, *ivp; struct inode *inode; long retval, i; - IO_fn_t fn; + io_fn_t fn; + iov_fn_t fnv; /* First get the "struct iovec" from user memory and * verify all the pointers */ if (!count) return 0; - if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count)) + if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count)) return -EFAULT; if (count > UIO_MAXIOV) return -EINVAL; @@ -1086,33 +1088,19 @@ static long do_readv_writev32(int type, struct file *file, retval = locks_verify_area((type == VERIFY_WRITE ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), inode, file, file->f_pos, tot_len); - if (retval) { - if (iov != iovstack) - kfree(iov); - return retval; - } + if (retval) + goto out; - /* Then do the actual IO. Note that sockets need to be handled - * specially as they have atomicity guarantees and can handle - * iovec's natively - */ - if (inode->i_sock) { - int err; - err = sock_readv_writev(type, inode, file, iov, count, tot_len); - if (iov != iovstack) - kfree(iov); - return err; + /* VERIFY_WRITE actually means a read, as we write to user space */ + fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev); + if (fnv) { + retval = fnv(file, iov, count, &file->f_pos); + goto out; } - if (!file->f_op) { - if (iov != iovstack) - kfree(iov); - return -EINVAL; - } - /* VERIFY_WRITE actually means a read, as we write to user space */ - fn = file->f_op->read; - if (type == VERIFY_READ) - fn = (IO_fn_t) file->f_op->write; + fn = (type == VERIFY_WRITE ? file->f_op->read : + (io_fn_t) file->f_op->write); + ivp = iov; while (count > 0) { void * base; @@ -1124,17 +1112,18 @@ static long do_readv_writev32(int type, struct file *file, count--; nr = fn(file, base, len, &file->f_pos); if (nr < 0) { - if (retval) - break; - retval = nr; + if (!retval) + retval = nr; break; } retval += nr; if (nr != len) break; } +out: if (iov != iovstack) kfree(iov); + return retval; } @@ -1147,7 +1136,8 @@ asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count) if(!file) goto bad_file; - if (file->f_op && file->f_op->read && (file->f_mode & FMODE_READ)) + if (file->f_op && (file->f_mode & FMODE_READ) && + (file->f_op->readv || file->f_op->read)) ret = do_readv_writev32(VERIFY_WRITE, file, vector, count); fput(file); @@ -1163,7 +1153,8 @@ asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count) file = fget(fd); if(!file) goto bad_file; - if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE)) + if (file->f_op && (file->f_mode & FMODE_WRITE) && + (file->f_op->writev || file->f_op->write)) ret = do_readv_writev32(VERIFY_READ, file, vector, count); fput(file); diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index cd4b3365c..8c9b7c9fd 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.48 2000/05/03 06:37:03 davem Exp $ +/* $Id: fault.c,v 1.49 2000/08/09 00:00:15 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index c469c6062..68b77cfab 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.13 1999/12/20 05:02:33 davem Exp $ +/* $Id: generic.c,v 1.14 2000/08/09 00:00:15 davem Exp $ * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 63994c51d..7eef97836 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.153 2000/07/27 01:05:15 davem Exp $ +/* $Id: init.c,v 1.154 2000/08/09 00:00:15 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) |